iripau.executable module¶
Execute Command-Line Interfaces (CLI) as Python functions.
Call an instance of Executable, or any of its attributes, passing
positional arguments as *args and optional arguments as **kwargs.
All of the quoting is handled automatically, so there is no need to handle spaces
nor any special characters such as single and double quotes.
The attributes of the object will be instances of Command.
The return value is an instance of subprocess.CompletedProcess.
Example
Make a docker wrapper:
docker = Executable("docker")
# docker --version
output = docker(version=True)
# docker run ubuntu:24.04 --volume=/tmp/data:/data:Z --name=test-container
output = docker.run("ubuntu:24.04", volume="/tmp/data:/data:Z", name="test-container")
# docker container rename test-container renamed-container
output = docker.container.rename("test-container", "renamed-container")
Note
All values for positional and optional arguments are converted to string
with str(value) before creating the final subproces command.
- class iripau.executable.Command(parent, command)[source]¶
Bases:
objectRun a command or sub-command of a CLI as a Python function.
The attributes of
Executablewill be instances of this class, as well as any other sub-attribute.- Parameters:
parent (
Executable|Command) – Object to call so the subprocess can actually be executed.command (
str) – Python identifier for a given command or cub-command.
- iripau.executable.make_command(command)[source]¶
Replace underscore with dash.
Suitable for a CLI that uses dashes as word-separator in their positional arguments.
- Parameters:
command (
str) – Python identifier referring to a CLI command or sub-command.- Return type:
str- Returns:
Final token to be used as a CLI positional argument.
- iripau.executable.make_option(option)[source]¶
Replace underscore with dash and prepend two more dashes.
Suitable for a CLI that uses dashes as word-separator in their positional arguments.
- Parameters:
option (
str) – Python identifier referring to a CLI optional argument.- Return type:
Tuple[str]- Returns:
The tokens that could be used as a CLI positional argument.
- class iripau.executable.Executable(executable, make_command=<function make_command>, make_option=<function make_option>, alias=None, run_args_prefix='_', run_function=None, **kwargs)[source]¶
Bases:
objectRun an executable as a Python callable.
- Parameters:
executable (
Union[Iterable[str],str]) – Path to an executable file or just the name if it exists in thePATH. Or tokens that refer to a command.make_command (
Callable[[str],str]) – Function to convert a Python identifier to the corresponding command positional argument for the CLI.make_option (
Callable[[str],Tuple[str]]) – Function to convert a Python identifier into the corresponding optional argument for the CLI.alias (
Union[Iterable[str],str]) – Alias forexecutable. Seealiasiniripau.subprocess.Popen.run_args_prefix (
str) – When calling an instance of this class, all of the**kwargsstarting with this prefix will be passed torun_functionafter removing the prefix.run_function (
Callable[[Iterable[str],Any],Any]) – The function that will actually run the process, wait for it and return asubprocess.CompletedProcess, preferably. IfNone, the default will beiripau.command.host_run().**kwargs – Keyword arguments to be passed to
run_functionevery time this object is called. Therun_args_prefixis not needed here.
Regarding optional arguments:
Most of the CLIs have a long and short version for the same option, for example
docker run -m 128manddocker run --memory=128m. By default only one of those option can be used:# docker run ubuntu:24.04 -m 128m docker.run("ubuntu:24.04", m="128m") # docker run ubuntu:24.04 --memory=128m docker.run("ubuntu:24.04", memory="128m")
But using the name of a short option in a Python function might reduce readability. To solve that issue, the
getmethod of a dictionary can be used asmake_option. The keys of the dictionaries would be the Python identifiers used when calling the object:options_map = { "config": ("-c",), "memory": ("-m"), "quiet": ("-q",) } docker = Executable("docker", make_option=options_map.get) # docker run ubuntu:24.04 -m 128m output = docker.run("ubuntu:24.04", memory="128m")
Also, the dictionary can be used in combination with the default function,
make_option(), or any other function to avoid having all of the options supported by the CLI in the dictionary:option_map = {...} def make_option(option): tokens = options_map.get(option) if tokens is None: tokens = make_option(option) return tokens docker = Executable("docker", make_option=make_option)
Tip
Using a dictionary can help on
make_commandas well.As you might have already noted, the values of the dictionary are tuples. If that tuple has more that one item, one of those will be chosen randomly. If the chosen option starts with
--, there will be a single token with the option and the value:--memory=128m. If not, there will be two tokens:-m 128m.Regarding the values that the optional arguments can have:
IfTrue, the option will be treated as a flag, with no value:From:help=TrueTo:--helpIfFalseorNone, the option will be ignored:From:help=Falseorhelp=NoneTo: Nothing, not even an empty stringIf an iterable and not a string, the option will be repeated for each item:From:env=["DB_PASS=0123", "DB_PORT=3210"]To:-e DB_PASS=0123 -e DB_PORT=3210