Tiramisu-cmdline-parser¶
This tutorial is intended to be a gentle introduction to Tiramisu command-line parser, a command-line parsing module that comes included with the Tiramisu’s library.
Note
There are a lot of other modules that fulfill the same task, namely getopt (an equivalent for getopt() from the C language) and argparse, from the python standard library.
tiramisu-cmdline-parser enables us to validate the command line,
wich is a quite different scope – much more powerfull. It is a
superset of the argparse module
What is Tiramisu-cmdline-parser ?¶
Tiramisu-cmdline-parser is a free project that turns Tiramisu’s Config into a command line interface.
It automatically generates arguments, help and usage messages. Tiramisu (or Tiramisu-API) validates all arguments provided by the command line’s user.
Tiramisu-cmdline-parser uses the well known argparse module and adds functionnalities upon it.
Installation¶
The best way is to use the python pip installer
And then type:
pip install tiramisu-cmdline-parser
Build a Tiramisu-cmdline-parser¶
Let’s show the sort of functionality that we are going to explore in this introductory tutorial.
We are going to start with a simple example, like making a proxy’s configuration script.
First we are going to build the corresponding Tiramisu config object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | from tiramisu import IPOption, PortOption, BoolOption, ChoiceOption, DomainnameOption, \
URLOption, NetworkOption, NetmaskOption, \
SymLinkOption, OptionDescription, Leadership, Config
proxy_mode = ChoiceOption('proxy_mode', 'Proxy\'s config mode', ('No proxy',
'Manual proxy configuration',
'Automatic proxy configuration URL'),
properties=('positional', 'mandatory'))
http_ip_address = IPOption('http_ip_address', 'Proxy\'s HTTP IP', properties=('mandatory',))
http_ip_short = SymLinkOption('i', http_ip_address)
http_port = PortOption('http_port', 'Proxy\'s HTTP Port', default='8080', properties=('mandatory',))
http_port_short = SymLinkOption('p', http_port)
manual_proxy = OptionDescription('manual_proxy', 'Manual proxy settings', [http_ip_address, http_ip_short, http_port, http_port_short],
requires=[{'option': proxy_mode, 'expected': 'Manual proxy configuration', 'action':'disabled', 'inverse':True}])
auto_config_url = URLOption('auto_config_url','Proxy\'s auto config URL', properties=('mandatory',))
auto_config_url_short = SymLinkOption('i', auto_config_url)
automatic_proxy = OptionDescription('automatic_proxy', 'Automatic proxy setting',
[auto_config_url, auto_config_url_short],
requires=[{'option': proxy_mode, 'expected': 'Automatic proxy configuration URL', 'action':'disabled', 'inverse': True}])
configuration = OptionDescription('configuration', None,
[manual_proxy, automatic_proxy])
no_proxy_domain = DomainnameOption('no_proxy_domain', 'Domain names for which proxy will be desactivated', multi=True)
no_proxy_network = NetworkOption('no_proxy_network', 'Network addresses', multi=True)
no_proxy_network_short = SymLinkOption('n', no_proxy_network)
no_proxy_netmask = NetmaskOption('no_proxy_netmask', 'Netmask addresses', multi=True, properties=('mandatory',))
no_proxy_network_leadership = Leadership('no_proxy_network', 'Network for which proxy will be desactivated', [no_proxy_network, no_proxy_netmask])
no_proxy = OptionDescription('no_proxy', 'Disabled proxy',
[no_proxy_domain, no_proxy_network_leadership],
requires=[{'option': proxy_mode, 'expected': 'No proxy', 'action':'disabled'}, {'option': proxy_mode, 'expected': None, 'action':'disabled'}])
dns_over_https = BoolOption('dns_over_https', 'Enable DNS over HTTPS', default=False)
root = OptionDescription('proxy', 'Proxy parameters',
[proxy_mode, configuration, no_proxy, dns_over_https])
def display_name(option, dyn_name):
return "--" + option.impl_getpath()
proxy_config = Config(root, display_name=display_name)
proxy_config.property.read_write()
|
Then we invopque the command line parsing library by creating a commandline parser, and we give the configuration’s object to it:
1 2 3 | from tiramisu_cmdline_parser import TiramisuCmdlineParser
parser = TiramisuCmdlineParser(proxy_config)
parser.parse_args()
|
Finally pretty printing the configuration:
1 2 | from pprint import pprint
pprint(proxy_config.value.dict())
|
Let’s display the help:
$ python3 src/proxy.py -h
usage: proxy.py [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic proxy
configuration URL}
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
Positional argument¶
First of all, we have to set the positional argument proxy_mode.
-
proxy_mode¶ As it’s a
ChoiceOption, you only have three choices:- No proxy
- Manual proxy configuration
- Automatic proxy configuration URL
Set proxy_mode to No proxy:
$ python3 src/proxy.py "No proxy"
{'dns_over_https': False,
'proxy_mode': 'No proxy'}
Requirements¶
Disabled options are not visible as arguments in the command line. Those parameters appears or disappears following the context:
$ python3 src/proxy.py "No proxy" -h
usage: proxy.py "No proxy" [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic
proxy configuration URL}
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
If proxy_mode is set to “Automatic proxy configuration URL”, some new options are visible:
$ python3 src/proxy.py "Automatic proxy configuration URL" -h
usage: proxy.py "Automatic proxy configuration URL" [-h] -i AUTO_CONFIG_URL
[--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]]
[--no_proxy.no_proxy_network.pop-no_proxy_network INDEX]
--no_proxy.no_proxy_network.no_proxy_netmask
INDEX NO_PROXY_NETMASK
[--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]]
[--dns_over_https]
[--no-dns_over_https]
{No proxy,Manual proxy
configuration,Automatic
proxy configuration URL}
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
configuration.automatic_proxy:
Automatic proxy setting
-i AUTO_CONFIG_URL, --configuration.automatic_proxy.auto_config_url AUTO_CONFIG_URL
Proxy's auto config URL
no_proxy:
Disabled proxy
--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]
Domain names for which proxy will be desactivated
no_proxy.no_proxy_network:
Network for which proxy will be desactivated
--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]
Network addresses
--no_proxy.no_proxy_network.pop-no_proxy_network INDEX
--no_proxy.no_proxy_network.no_proxy_netmask INDEX NO_PROXY_NETMASK
Netmask addresses
Arguments¶
Each option creates an argument. To change the value of this option, just launch the application with the appropriate argument:
$ python3 src/proxy.py "Manual proxy configuration" \
--configuration.manual_proxy.http_ip_address 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
Fullpath argument or named argument¶
By default, arguments are build with fullpath of option.
The option http_ip_address is in manual_proxy optiondescription, which is also in configuration optiondescription.
So the argument is --configuration.manual_proxy.http_ip_address:
$ python3 src/proxy.py "Manual proxy configuration" \
--configuration.manual_proxy.http_ip_address 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
If we set fullpath to False:
parser = TiramisuCmdlineParser(proxy_config, fullpath=False)
Arguments are build with the name of the option.
The option http_ip_address is now :option`–http_ip_address`:
$ python3 src/proxy.py "Manual proxy configuration" \
--http_ip_address 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
Short argument¶
To have short argument, you just have to make SymLinkOption to this option:
1 2 | http_ip_address = IPOption('http_ip_address', 'Proxy\'s HTTP IP', properties=('mandatory',))
http_ip_short = SymLinkOption('i', http_ip_address)
|
Now argument -i or --configuration.manual_proxy.http_ip_address can be used alternatively:
$ python3 src/proxy.py "Manual proxy configuration" \
--configuration.manual_proxy.http_ip_address 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
$ python3 src/proxy.py "Manual proxy configuration" \
-i 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
Be carefull, short argument have to be uniqe in the whole configuration.
Here -i argument is define a second time in same Config:
1 2 | auto_config_url = URLOption('auto_config_url','Proxy\'s auto config URL', properties=('mandatory',))
auto_config_url_short = SymLinkOption('i', auto_config_url)
|
But http_ip_address and auto_config_url are not accessible together:
http_ip_addressis visible only ifproxy_modeis “Manual proxy configuration”auto_config_urlis only visible whenproxy_modeis “Automatic proxy configuration URL”
Boolean argument¶
Boolean option creates two arguments:
- –<boolean_name>: it activates (set to True) the option
- –no-<boolean_name>: it deactivates (set to False) the option
$ python3 src/proxy.py "No proxy" \
--dns_over_https
{'dns_over_https': True,
'proxy_mode': 'No proxy'}
$ python3 src/proxy.py "No proxy" \
--no-dns_over_https
{'dns_over_https': False,
'proxy_mode': 'No proxy'}
Multi¶
Some values are multi. So we can set several value for this option.
For example, we can set serveral domain (cadoles.com and gnu.org) to “Domain names for which proxy will be desactivated” option:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url http://proxy.cadoles.com/proxy.pac \
--no_proxy.no_proxy_domain cadoles.com gnu.org
{'configuration.automatic_proxy.auto_config_url': 'http://proxy.cadoles.com/proxy.pac',
'configuration.automatic_proxy.i': 'http://proxy.cadoles.com/proxy.pac',
'dns_over_https': False,
'no_proxy.no_proxy_domain': ['cadoles.com', 'gnu.org'],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Automatic proxy configuration URL'}
Leadership¶
Leadership option are also supported. The leader option is a standard multi option. But follower option are not view as a multi option. Follower value are separate and we need to set index to set a follower option.
If we want to had two “Network for which proxy will be desactivated”:
- 192.168.1.1/255.255.255.255
- 192.168.0.0/255.255.255.0
We have to do:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url http://proxy.cadoles.com/proxy.pac \
--no_proxy.no_proxy_network.no_proxy_network 192.168.1.1 192.168.0.0 \
--no_proxy.no_proxy_network.no_proxy_netmask 0 255.255.255.255 \
--no_proxy.no_proxy_network.no_proxy_netmask 1 255.255.255.0
{'configuration.automatic_proxy.auto_config_url': 'http://proxy.cadoles.com/proxy.pac',
'configuration.automatic_proxy.i': 'http://proxy.cadoles.com/proxy.pac',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': ['255.255.255.255',
'255.255.255.0'],
'no_proxy.no_proxy_network.no_proxy_network': ['192.168.1.1', '192.168.0.0'],
'proxy_mode': 'Automatic proxy configuration URL'}
We cannot reduce leader lenght:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url http://proxy.cadoles.com/proxy.pac \
--no_proxy.no_proxy_network.no_proxy_network 192.168.1.1 192.168.0.0 \
--no_proxy.no_proxy_network.no_proxy_netmask 0 255.255.255.255 \
--no_proxy.no_proxy_network.no_proxy_netmask 1 255.255.255.0 \
--no_proxy.no_proxy_network.no_proxy_network 192.168.1.1
usage: proxy.py -i "http://proxy.cadoles.com/proxy.pac" --no_proxy.no_proxy_network.no_proxy_network "192.168.1.1" "192.168.0.0" "Automatic proxy configuration URL"
[-h] -i AUTO_CONFIG_URL
[--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]]
[--no_proxy.no_proxy_network.pop-no_proxy_network INDEX]
--no_proxy.no_proxy_network.no_proxy_netmask INDEX NO_PROXY_NETMASK
[--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]]
[--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
proxy.py: error: cannot reduce length of the leader "--no_proxy.no_proxy_network.no_proxy_network"
So an argument –pop-<leader> is automatically created. You need to specified index as parameter:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url http://proxy.cadoles.com/proxy.pac \
--no_proxy.no_proxy_network.no_proxy_network 192.168.1.1 192.168.0.0 \
--no_proxy.no_proxy_network.no_proxy_netmask 0 255.255.255.255 \
--no_proxy.no_proxy_network.pop-no_proxy_network 1
{'configuration.automatic_proxy.auto_config_url': 'http://proxy.cadoles.com/proxy.pac',
'configuration.automatic_proxy.i': 'http://proxy.cadoles.com/proxy.pac',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': ['255.255.255.255'],
'no_proxy.no_proxy_network.no_proxy_network': ['192.168.1.1'],
'proxy_mode': 'Automatic proxy configuration URL'}
Validation¶
All arguments are validated successively by argparser and Tiramisu:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url cadoles.com
usage: proxy.py "Automatic proxy configuration URL" [-h] -i AUTO_CONFIG_URL
[--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]]
[--no_proxy.no_proxy_network.pop-no_proxy_network INDEX]
--no_proxy.no_proxy_network.no_proxy_netmask
INDEX NO_PROXY_NETMASK
[--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]]
[--dns_over_https]
[--no-dns_over_https]
{No proxy,Manual proxy
configuration,Automatic
proxy configuration URL}
proxy.py: error: "cadoles.com" is an invalid URL for "Proxy’s auto config URL", must start with http:// or https://
In error message, we have the option description (“Proxy’s auto config URL”) by default.
That why we redefined display_name function:
1 2 3 4 | def display_name(option, dyn_name):
return "--" + option.impl_getpath()
proxy_config = Config(root, display_name=display_name)
|
Now we have –<path> as description:
$ python3 src/proxy.py "Automatic proxy configuration URL" \
--configuration.automatic_proxy.auto_config_url cadoles.com
usage: proxy.py "Automatic proxy configuration URL" [-h] -i AUTO_CONFIG_URL
[--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]]
[--no_proxy.no_proxy_network.pop-no_proxy_network INDEX]
--no_proxy.no_proxy_network.no_proxy_netmask
INDEX NO_PROXY_NETMASK
[--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]]
[--dns_over_https]
[--no-dns_over_https]
{No proxy,Manual proxy
configuration,Automatic
proxy configuration URL}
proxy.py: error: "cadoles.com" is an invalid URL for "--configuration.automatic_proxy.auto_config_url", must start with http:// or https://
Mandatory¶
Obviously the mandatory options are checked.
The positional argument is mandatory, so if we don’t set it, an error occured:
$ python3 src/proxy.py
usage: proxy.py [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic proxy
configuration URL}
proxy.py: error: the following arguments are required: proxy_mode
Others arguments are also check:
$ python3 src/proxy.py "Automatic proxy configuration URL"
usage: proxy.py "Automatic proxy configuration URL" [-h] -i AUTO_CONFIG_URL
[--no_proxy.no_proxy_network.no_proxy_network [NO_PROXY_NETWORK [NO_PROXY_NETWORK ...]]]
[--no_proxy.no_proxy_network.pop-no_proxy_network INDEX]
--no_proxy.no_proxy_network.no_proxy_netmask
INDEX NO_PROXY_NETMASK
[--no_proxy.no_proxy_domain [NO_PROXY_DOMAIN [NO_PROXY_DOMAIN ...]]]
[--dns_over_https]
[--no-dns_over_https]
{No proxy,Manual proxy
configuration,Automatic
proxy configuration URL}
proxy.py: error: the following arguments are required: --configuration.automatic_proxy.auto_config_url
Persistence configuration and mandatories validation¶
First of all, activate persistence configuration and remove mandatory validation:
1 2 3 4 | from tiramisu import default_storage
default_storage.setting(engine='sqlite3')
proxy_config = Config(root, display_name=display_name, persistent=True, session_id='proxy')
|
We can disabled mandatory validation in parse_args function.
1 | parser.parse_args(valid_mandatory=False)
|
In this case, we can store incomplete value:
$ python3 src/proxy_persistent.py 'Manual proxy configuration'
{'configuration.manual_proxy.http_ip_address': None,
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': None,
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
We can complete configuration after:
$ python3 src/proxy_persistent.py -i 192.168.1.1
{'configuration.manual_proxy.http_ip_address': '192.168.1.1',
'configuration.manual_proxy.http_port': '8080',
'configuration.manual_proxy.i': '192.168.1.1',
'configuration.manual_proxy.p': '8080',
'dns_over_https': False,
'no_proxy.no_proxy_domain': [],
'no_proxy.no_proxy_network.no_proxy_netmask': [],
'no_proxy.no_proxy_network.no_proxy_network': [],
'proxy_mode': 'Manual proxy configuration'}
When configuration is already set, help command, display already set options is usage ligne.
$ python3 src/proxy_persistent.py -h
usage: proxy_persistent.py -i "192.168.1.1" "Manual proxy configuration"
[..]
Description and epilog¶
As argparser, description and epilog message can be added to the generated help:
parser = TiramisuCmdlineParser(proxy_config, description='New description!', epilog='New epilog!')
$ python3 src/proxy.py -h
usage: proxy.py [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic proxy
configuration URL}
New description!
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
New epilog!
By default, TiramisuCmdlineParser objects line-wrap the description and epilog texts in command-line help messages.
If there are line breaks in description or epilog, it automatically replace by a space. You need to change formatter class:
from argparse import RawDescriptionHelpFormatter
parser = TiramisuCmdlineParser(proxy_config, description='New description!\nLine breaks', epilog='New epilog!\nLine breaks', formatter_class=RawDescriptionHelpFormatter)
$ python3 src/proxy.py -h
usage: proxy.py [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic proxy
configuration URL}
New description!
Line breaks
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
New epilog!
Line breaks
Hide empty optiondescription¶
An empty optiondescription, is an optiondescription without any option (could have others optiondescriptions).
For example, configuration is an empty optiondescription:
1 2 | configuration = OptionDescription('configuration', None,
[manual_proxy, automatic_proxy])
|
This optiondescription doesn’t appears in help:
$ python3 src/proxy.py "No proxy" -h
usage: proxy.py "No proxy" [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic
proxy configuration URL}
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
This behavior is, in fact, due to two conditions:
- there is no option
- there is no description (None)
If we add description:
configuration = OptionDescription('configuration', 'Configuration',
[manual_proxy, automatic_proxy])
This optiondescription is specified in help:
$ python3 src/proxy.py "No proxy" -h
usage: proxy.py "No proxy" [-h] [--dns_over_https] [--no-dns_over_https]
{No proxy,Manual proxy configuration,Automatic
proxy configuration URL}
positional arguments:
{No proxy,Manual proxy configuration,Automatic proxy configuration URL}
Proxy's config mode
optional arguments:
-h, --help show this help message and exit
--dns_over_https Enable DNS over HTTPS
--no-dns_over_https
configuration:
Configuration
If you don’t want empty optiondescription even if there is a description, you could add remove_empty_od to True in parse_args function:
parser = TiramisuCmdlineParser(proxy_config, remove_empty_od=True)
SubConfig¶
Entire Config is transformed into an argument by default.
It could be interesting to display only ‘configuration’ OptionDescription.
To do this, we have to define default all mandatories options outside this scope:
proxy_mode = ChoiceOption('proxy_mode', 'Proxy\'s config mode', ('No proxy',
'Manual proxy configuration',
'Automatic proxy configuration URL'),
default='Manual proxy configuration',
properties=('positional', 'mandatory'))
Finally specified the root argument to TiramisuCmdlineParser:
parser = TiramisuCmdlineParser(proxy_config, root='configuration')
Now, only sub option of configuration is proposed:
$ python3 src/proxy.py -h
usage: proxy.py [-h] -i HTTP_IP_ADDRESS -p [HTTP_PORT]
optional arguments:
-h, --help show this help message and exit
configuration.manual_proxy:
Manual proxy settings
-i HTTP_IP_ADDRESS, --configuration.manual_proxy.http_ip_address HTTP_IP_ADDRESS
Proxy's HTTP IP
-p [HTTP_PORT], --configuration.manual_proxy.http_port [HTTP_PORT]
Proxy's HTTP Port