Command Line Interface¶
User guide¶
The command line interface has built in help. To display the help, please append -h to the program call, for example:
./patapy.py -h
The help option responds to arguments your provide, so you can get details about your method of choice with:
./patapy.py gsea -h
where gsea is the name of a method; likewise, you can display help for any of samples specification options (case/control/data), e.g.:
./patapy.py control -h
Predefined parsers¶
Parsers are defined in command_line.main
module.
-
class
CLI
(parser_name=None, **kwargs)[source]¶ The main parser, the one exposed directly to the user.
-
parse_args
(args)[source]¶ Same as
parse_known_args()
but all arguments must be parsed.This is an equivalent of
argparse.ArgumentParser.parse_args()
although it does >not< support namespace keyword argument.Comparing to
parse_known_args()
, this method handles help messages nicely (i.e. passes everything toargparse
).Parameters: args – strings to parse, default is sys.argv[1:]
-
produce
(unknown_args)[source]¶ Post-process already parsed namespace.
You can override this method to create a custom objects in the parsed namespace (e.g. if you cannot specify the target class with Argument(type=X), because X depends on two or more arguments).
You can chery-pick the arguments which were not parsed by the current parser (e.g. when some step of parsing depends on provided arguments), but please remember to remove those from unknown_args list.
Remember to operate on the provided list object (do not rebind the name with unknown_args = [], as doing so will have no effect: use unknown_args.remove() instead).
-
-
class
CLIExperiment
(parser_name=None, **kwargs)[source]¶ Use both: case and control or data to create an Experiment.
-
produce
(unknown_args=None)[source]¶ Post-process already parsed namespace.
You can override this method to create a custom objects in the parsed namespace (e.g. if you cannot specify the target class with Argument(type=X), because X depends on two or more arguments).
You can chery-pick the arguments which were not parsed by the current parser (e.g. when some step of parsing depends on provided arguments), but please remember to remove those from unknown_args list.
Remember to operate on the provided list object (do not rebind the name with unknown_args = [], as doing so will have no effect: use unknown_args.remove() instead).
-
-
class
PhenotypeFactory
(parser_name=None, **kwargs)[source]¶ Provide {parser_name} samples. Requires a file (or files) with samples.
The files should come in Delimiter Separated Values format (like .csv or .tsv). The default delimiter is a tab character. The first column of each file should contain gene identifiers.
To use only a subset of samples from files(s) specify column numbers (–columns) or sample names (–samples) of desired samples.
-
produce
(unknown_args=None)[source]¶ Post-process already parsed namespace.
You can override this method to create a custom objects in the parsed namespace (e.g. if you cannot specify the target class with Argument(type=X), because X depends on two or more arguments).
You can chery-pick the arguments which were not parsed by the current parser (e.g. when some step of parsing depends on provided arguments), but please remember to remove those from unknown_args list.
Remember to operate on the provided list object (do not rebind the name with unknown_args = [], as doing so will have no effect: use unknown_args.remove() instead).
-
-
class
SingleFileExperimentFactory
(parser_name=None, **kwargs)[source]¶ Provide both: case and control samples from a single file.
This is just a shortcut for specifying the same file for both: case and control samples sets. You have to provide –case or –control (or both) to specify which columns contain controls.
If you specify only one of –case and –control, it will be assumed that all other columns should be used for the other set of samples (if you use –case 0,1,2 and your file has five columns with samples, then columns three and four will be used to create control samples).
To enable more advanced features, please use control`&`case options (instead of the currently selected data sub-parser).
-
produce
(unknown_args=None)[source]¶ Post-process already parsed namespace.
You can override this method to create a custom objects in the parsed namespace (e.g. if you cannot specify the target class with Argument(type=X), because X depends on two or more arguments).
You can chery-pick the arguments which were not parsed by the current parser (e.g. when some step of parsing depends on provided arguments), but please remember to remove those from unknown_args list.
Remember to operate on the provided list object (do not rebind the name with unknown_args = [], as doing so will have no effect: use unknown_args.remove() instead).
-
Creating custom arguments and parsers¶
Please use command_line.parser
module to create custom parsers and arguments.
-
class
Argument
(name=None, short=None, optional=True, as_many_as=None, **kwargs)[source]¶ Defines argument for Parser.
In essence, this is a wrapper for
argparse.ArgumentParser.add_argument()
, so most options (type, help) which work in standard Python parser will work with Argument too. Additionally, some nice features, like automated naming are available.Worth to mention that when used with
MethodParser
, type and help will be automatically deduced.
-
class
Parser
(parser_name=None, **kwargs)[source]¶ Parser is a wrapper around Python built-in
argparse.ArgumentParser
.Subclass the Parser to create your own parser.
Use help, description and epilog properties to adjust the help screen. By default help and description will be auto-generated using docstring and defined arguments.
Attach custom arguments and sub-parsers by defining class-variables with
Argument
andParser
instances.Example:
class TheParser(Parser): help = 'This takes only one argument, but it is required' arg = Argument(optional=False, help='This is required') class MyParser(Parser): description = 'This should be a longer text' my_argument = Argument(type=int, help='some number') my_sub_parser = TheParser() epilog = 'You can create a footer with this' # To execute the parser use: parser = MyParser() # The commands will usually be `sys.argv[1:]` commands = '--my_argument 4 my_sub_parser value'.split() namespace = parser.parse_args(commands) # `namespace` is a normal `argparse.Namespace` assert namespace.my_argument == 4 assert namespace.my_sub_parser.arg == 'value'
Implementation details:
To enable behaviour not possible with limited, plain ArgumentParser (e.g. to dynamically attach a sub-parser, or to chain two or more sub-parsers together) the stored actions and sub-parsers are:
- not attached permanently to the parser,
- attached in a tricky way to enable desired behaviour,
- executed directly or in hierarchical order.
Class-variables with parsers will be deep-copied on initialization, so you do not have to worry about re-use of parsers.
-
attach_argument
(argument, parser=None)[source]¶ Attach Argument instance to given (or own) argparse.parser.
-
attach_subparsers
()[source]¶ Only in order to show a nice help, really.
There are some issues when using subparsers added with the built-in add_subparsers for parsing. Instead subparsers are handled in a custom implementation of parse_known_args (which really builds upon the built-in one, just tweaking some places).
-
bind_parser
(parser, name)[source]¶ Bind deep-copy of Parser with this instance (as a sub-parser).
Parameters: - parser (
Parser
) – parser to be bound as a sub-parser (must be already initialized) - name – name of the new sub-parser
This method takes care of ‘translucent’ sub-parsers (i.e. parsers which expose their arguments and sub-parsers to namespace above), saving their members to appropriate dicts (lifted_args/parsers).
- parser (
-
description
¶ Longer description of the parser.
Description is shown when user narrows down the help to the parser with:
./run.py sub_parser_name -h
.
-
epilog
¶ Use this to append text after the help message
-
help
¶ A short message, shown as summary on >parent< parser help screen.
Help will be displayed for sub-parsers only.
-
parse_args
(args=None)[source]¶ Same as
parse_known_args()
but all arguments must be parsed.This is an equivalent of
argparse.ArgumentParser.parse_args()
although it does >not< support namespace keyword argument.Comparing to
parse_known_args()
, this method handles help messages nicely (i.e. passes everything toargparse
).Parameters: args ( Optional
[Sequence
[str
]]) – strings to parse, default is sys.argv[1:]
-
parse_known_args
(args)[source]¶ Parse known arguments, like
argparse.ArgumentParser.parse_known_args()
.- Additional features (when compared to argparse implementation) are:
- ability to handle multiple sub-parsers
- validation with self.validate (run after parsing)
- additional post-processing with self.produce (after validation)
-
produce
(unknown_args)[source]¶ Post-process already parsed namespace.
You can override this method to create a custom objects in the parsed namespace (e.g. if you cannot specify the target class with Argument(type=X), because X depends on two or more arguments).
You can chery-pick the arguments which were not parsed by the current parser (e.g. when some step of parsing depends on provided arguments), but please remember to remove those from unknown_args list.
Remember to operate on the provided list object (do not rebind the name with unknown_args = [], as doing so will have no effect: use unknown_args.remove() instead).
-
pull_to_namespace_above
¶ Makes the parser “translucent” for the end user.
Though parsing methods (as well as validate & produce) are still evaluated, the user won’t be able to see this sub-parser in command-line interface.
This is intended to provide additional logic separation layer & to keep the parsers nicely organized and nested, without forcing the end user to type in prolonged names to localise an argument in a sub-parser of a sub-parser of some other parser.