Execute one of the PTS command scripts from the command line. More...
Classes | |
class | ArgumentParserError |
An instance of this class is raised as an exception when the argument parser wants to "exit" because of a user request for help or because of an error in the command line. More... | |
class | CommandScript |
The CommandScript class encapsulates a particular PTS command script. More... | |
class | LoggingArgumentParser |
This class overrides the output functions in the argument parser to send all output to the logger instead of directly to stdin or stderr. More... | |
Functions | |
def | doWithCommandLineArguments (arguments=None) |
This function locates the PTS command script corresponding to the first command line argument, and then invokes it with the remaining command line arguments. More... | |
def | listCommands () |
This public function lists all available PTS commands, per package. More... | |
Execute one of the PTS command scripts from the command line.
This module enables command scripts to be executed from the command line to expose PTS functionality to a terminal session. The doWithCommandLineArguments() function is invoked from the __main__ module in the do
package when that package is specified on the python command line.
Acessing command scripts
Typical usage is as follows:
alias pts='export PYTHONPATH=~/SKIRT/PTS9 ; python -m pts.do' ... pts try me
Command scripts are located in the do
subdirectory of each PTS package (an immediate subdirectory of the top-level pts
directory). To access a script, the first argument on the command line (after the -m option) must specify its package and script names separated by a forward slash. The remaining command line arguments are passed to the script.
Several shortcuts are allowed for the package and script names, as long as these shortcuts do not result in any ambiguities. The package name can be omitted, and if the script name contains underscores, each of the segments between the underscores can be used instead of the full script name. Also, any name can be shortened to an initial subset of the name.
For example, assume that a command script called try_do.py
resides in the do
subdirectory of the admin
package, and that this script accepts a single string argument. Assuming that none of the other command scripts match the same shortcut, this script can be accessed by any of the following commands,
pts admin/try_do me pts ad/tr me pts tr "you and me" pts do "you and me"
Defining the do() function
A PTS command script must define a top-level function called do()
with a number of positional and/or optional parameters as required by the script. These parameters must be declared in a specific way as described below. The doWithCommandLineArguments() function in this module inspects the function signature to obtain information about the number of parameters and the semantics of each parameter. This information is then used to create a command line argument parser (including help text), and to translate command line arguments to function argument values.
For example, the try_do script used in the previous example could have a function declaration as follows:
def do( aFixedString : (str,"first and only positional argument"), aString : (str,"optional string argument") = "PTS is great", aFloat : (float,"optional float argument") = 3.14, anInteger : (int,"optional integer argument") = 7, ) -> "try the PTS command mechanism":
The following rules apply:
With the above definition of the do() function, requesting help from the command line results in:
$ pts try --help usage: pts [-h] [--aString <str>] [--aFloat <float>] [--anInteger <int>] admin/try_do aFixedString admin/try_do: try the PTS command mechanism positional arguments: admin/try_do packagename/scriptname aFixedString first and only positional argument optional arguments: -h, --help show this help message and exit --aString <str> optional string argument (default: PTS is great) --aFloat <float> optional float argument (default: 3.14) --anInteger <int> optional integer argument (default: 7)
And here's an example of providing optional arguments on the command line:
$ pts try me --aFloat 8.3 --anInteger 17 Starting admin/try_do... Command line arguments are: Fixed string: me Optional string: PTS is great Float number: 8.3 Integer number: 17 Finished admin/try_do...
The do() function body
The body of the do() function in a command script should be fairly short. Preferably, most if not all of the functionality is implemented in other modules residing in the same package as the command script (but outside of the do
directory). The interface offered by these modules can then also be used by other code internal or external to PTS.
Furthermore, contrary to what is recommended and customary for modules, import statements in command scripts are preferably placed inside the do() function body. This allows the command script to be imported (for example to retrieve the do() function signature) without recursively performing its own imports.
Logging and error reporting
The functions in this module setup the standard logging package with appropriate formatting. To ensure consistent output and error handling, the following rules apply during the execution of a command script, and by extension in all PTS code.
def pts.do.command.doWithCommandLineArguments | ( | arguments = None | ) |
This function locates the PTS command script corresponding to the first command line argument, and then invokes it with the remaining command line arguments.
If the arguments are omitted, the function obtains the command line arguments from the system.
def pts.do.command.listCommands | ( | ) |
This public function lists all available PTS commands, per package.