lucky_start_izumi
lucky_start_izumi

Reputation: 2591

about argparse when using fabric

I am new to python & fabric. I have a python module module1.py which would like to take in a command parameter, we use argparse inside the module1.py to require a command line parameter. But we are trying to run the whole program through fabric, if I directly specify the command line when running through fab, I got

mycode.py: error: argument --config_yaml is required

How could I pass the argument through fab?

Thanks!

Upvotes: 2

Views: 512

Answers (2)

Javier Buzzi
Javier Buzzi

Reputation: 6808

From what i can see from here:

https://github.com/fabric/fabric/blob/master/fabric/main.py#L340 https://github.com/fabric/fabric/blob/master/fabric/main.py#L619

You CAN'T do it. You can't add things to env_options before main.py runs, your code inside fabfile.py will run after main() has already been processed.

You can however do this:

Rename fabfile.py -> whatever you want as long as its not fabric.py. I called mine fabricc.py

from fabric.state import env_options, make_option

env_options.append(make_option('--myconfig', dest='config_file', default='default.ini'))

from fabric import main
from fabric.api import task, env

@task
def do_something():
    print('config file: {}'.format(env.config_file))


if __name__ == '__main__':
    main.find_fabfile = lambda x: __file__
    main.main()

now run it:

$ python fabricc.py do_something
config file: default.ini

Done.

or..

$ python fabricc.py do_something --myconfig=somethinelse.ini
config file: somethinelse.ini

Done.

Word of warning DO NOT call it --config -- this is a builtin param.

With this you still enjoy everything you still love about fabric and nothing has changed.

$ python fabricc.py do_something --help
Usage: fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...

Options:
  -h, --help            show this help message and exit
  -d NAME, --display=NAME
...
  -z INT, --pool-size=INT
                        number of concurrent processes to use in parallel mode
  --myconfig=CONFIG_FILE

PS. i dont suggest you do the fabric override to handle it manually. Im just showing you it can be done. (the reason i dont condone this is: compatibility. If the version changes tomorrow this might break) best to use the product how the author meant it to be used.

====================================================================

Also, fabric is meant to be a fancy orm builder -- for lack of a better word. You cannot have command line arguments on a per-task-basis, it wasnt design to work like that. BUT it was designed to take in task-function arguments:

@task
def do_something(file=None):
    print('config file: {}'.format(file or 'default.ini'))

$ fab dosomething:test
config file: override.ini

Done.

and that is what fabric was created to do.

its meant to be used like this:

@task
def environment(box_env=None):
    ...

@task
def deploy(branch='master'):
    ...

@task
def provision(recreate_if_existing=False, start_nignx=True):
    ...

fab evironment:dev deploy:development

fab evironment:dev provision:True,False

all together.

fab evironment:dev provision deploy:development

Upvotes: 1

hpaulj
hpaulj

Reputation: 231385

I know argparse, but not fabric. From the error is looks like your script defines a '--config_yaml' argparse argument (and makes it 'required'). But fabric apparently also uses that argument name.

I don't know if fabric also uses argparse. But it is common for programs like that to strip off the commandline arguments that it expects, and pass the rest on to your code.

Do you need to use --config_yaml in your script? And why is it set to required=True? argparse allows you to specify a required parameter, but ideally flagged arguments like this are optional. If not given they should have a reasonable default.


I see a --config=... argument in the fabric API, but not a --config_yaml.

I wonder if this section about per-task arguments is relevant

http://docs.fabfile.org/en/1.10/usage/fab.html#per-task-arguments

It sounds like you need to add the task name to the argument. fabric doesn't just pass all unknown arguments to the task (which is what I was assuming above). But I don't have fabric installed, so can't test it.

Upvotes: 0

Related Questions