Command line interface¶
This document describes logic ricecooker
uses to parse command line arguments.
Under normal use cases you shouldn’t need modify the command line parsing, but
you need to understand how argparse
works if you want to add new command line
arguments for your chef script.
Summary¶
A sushi chef script using the new API looks like this:
#!/usr/bin/env python
...
...
class MySushiChef(BaseChef): # or SushiChef to support remote monitoring
def get_channel(**kwargs)` -> ChannelNode (bare channel, used just for info)
...
def construct_channel(**kwargs) -> ChannelNode (with populated Tree)
...
...
...
if __name__ == '__main__':
chef = MySushiChef()
chef.main()
Flow diagram¶
The call to chef.main()
results in the following sequence of six calls:
MySushiChef -----extends----> BaseChef commands.uploadchannel
--------------------------- ----------------------- -----------------------
1. main()
2. parse_args_and_options()
3. run(args, options)
4. uploadchannel(chef, *args, **options)
...
5. get_channel(**kwargs)
...
6. construct_channel(**kwargs)
...
...
DONE
Changes¶
Old uploadchannel
API (a.k.a. compatibility mode)¶
- pass in chef script file as
"<file_path>"
to uploadchannel uploadchannel
calls the functioncontruct_channel
defined in the chef script
New uploadchannel
API¶
The chef script defines subclass of
riececooker.chefs.SushiChef
that implement the methodsget_channel
andconstruct_channel
:class MySushiChef(riececooker.chefs.SushiChef): def get_channel(**kwargs)` -> ChannelNode (bare channel, used just for info) ... def construct_channel(**kwargs): --> ChannelNode (with populated Tree) ...
Each chef script is a standalone python executable. The
main
method of the chef instance is the entry point used by a chef script:#!/usr/bin/env python ... ... ... if __name__ == '__main__': chef = MySushiChef() chef.main()
The
__init__
method of the sushi chef class configures anargparse
parser (BaseChef
createsself.arg_parser
and each class adds to this shared parser its own command line arguments.)The
main
method of the class parses the command line arguments and calls therun
method (or thedeamon_mode
method.)class BaseChef(): ... def main(self): args, options = self.parse_args_and_options() self.run(args, options)
The chef’s
run
method callsuploadchannel
(oruploadchannel_wrapper
)class BaseChef(): ... def run(self, args, options): ... uploadchannel(self, **args.__dict__, **options)
note the chef instance is passed as the first argument, and not path.
The
uploadchannel
function expects the sushi chef class to implement the following two methods:get_channel(**kwargs)
: returns a ChannelNode (previously calledcreate_channel
)- as an alternative, if
MySushiChef
has achannel_info
attribute (a dict) then the default SushiChef.get_channel will create the channel from this info
- as an alternative, if
construct_channel(**kwargs)
: create the channel and build node tree
Additionally, the
MySushiChef
class can implement the following optional methods that will be called as part of the run__init__
: if you want to add custom chef-specific command line arguments using argparsepre_run
: if you need to do something before chef run starts (called byrun
)run
: in case you want to calluploadchannel
yourself
Compatibility mode¶
Calling ricecooker as a module (python -m ricecooker uploadchannel oldchef.py ...
)
will run the following code in ricecooker.__main__.py
:
from ricecooker.chefs import BaseChef
if __name__ == '__main__':
chef = BaseChef(compatibility_mode=True)
chef.main()
The BaseChef
class with compatibility_mode=True
proxies call to its construct_channel
method to the function construct_channel
in oldchef.py
.
The call to chef.main()
results in the following sequence of events:
oldchef.py BaseChef(compat mode) commands.uploadchannel
--------------------------- ----------------------- -----------------------
1. main()
2. parse_args_and_options()
3. run(args, options)
4. uploadchannel(chef, *args, **options)
...
...
5. construct_channel(**kwargs)
5'. construct_channel(**kwargs)
...
...
DONE
Logging and progress reporting to SushiBar server is not supported in compatibility mode.
Args, options, and kwargs¶
There are three types of arguments involved in a chef run:
args
(dict): command line args as parsed by the sushi chef class and its parents- BaseChef: the method
BaseChef.__init__
configures argparse for the following:compress
,download_attempts
,prompt
,publish
,reset
,resume
,stage
,step
,thumbnails
,token
,update
,verbose
,warn
- in compatibility mode, also handles
uploadchannel
andchef_script
positional arguments
- SushiChef:
daemon
= Runs in daemon modenomonitor
= Disable SushiBar progress monitoring
- MySushiChef: the chef’s
__init__
method can define additional cli args
- BaseChef: the method
options
(dict): additional [OPTIONS…] passed at the end of the command line- used for compatibility mode with old rieceooker API (
python -m ricecooker uploadchannel ... key=value
)
- used for compatibility mode with old rieceooker API (
kwargs
(dict): chef-specific keyword arguments not handled by ricecooker’suploadchannel
method- the chef’s
run
method makes the calluploadchannel(self, **args.__dict__, **options)
while the definition ofuploadchannel
looks likeuploadchannel(chef, verbose=False, update=False, ... stage=False, **kwargs)
sokwargs
contains a mix of bothargs
andoptions
that are not explicitly expected by theuploadchannel
function - The function
uploadchannel
will pass**kwargs
on to thechef
’sget_channel
andconstruct_channel
methods as part of the chef run.
- the chef’s
Daemon mode¶
In daemon mode, we open a ControlWebSocket
connection with the SushiBar and
wait for commands.
When a command comes in on the control channel, it looks like this:
message = {"command":"start", "args":{...}, "options":{...}}
Then the handler ControlWebSocket.on_message
will start a new run:
args.update(message['args']) # remote arguments overwrite ricecooker cli args
options.update(message['options']) # remote options overwrite cli options
chef.run(args, options)
After finishing the run, a chef started with the --daemon
option remains connected
to the SushiBar server and listens for more commands.