Question

I have a fabfile (fabfile.py) with some tasks declared:

# fabfile.py
from fabric.api import *

@task
def start():
  # code

@task
def stop():
  # code

Then when I try to call any of those tasks using the execute function from fabric like this:

# main.py
from fabric.api import execute
from fabfile import * # I don't really know if this is necessary 
                      # or how should it be done
def main():
  execute('start')

It raises this error:

Fatal error: None is not callable or a valid task name

My intention is to make a kind of wrapper for some tasks specified in that fabfile that can be called with different arguments, and the task to perform must be taken from the arguments when you make a call to this main program, so I can't explicitly call the function, but use the task names.

How would this be done? Maybe I'm misunderstanding how fabric is supposed to work?

Thank you

Was it helpful?

Solution

Change execute('start') to execute(start).

I didn't find out why pass a taskname to execute did not work, but there is a workaround:

import fabfile
execute(getattr(fabfile, 'start'))

Update: After reading a bit code and doing some test of fabric, I think execute('task_name') can only be used when fabric tasks are loaded. By default you can use it in the fabfile.py like this:

@task
def task1():
    #do task1

@task
def task2():
    #do task2

@task
def task3():
    #do task1 and task2
    execute('task1')
    execute('task2')

Then you can use fab task3 to execute task1 and task2 together. But till now, I am still using fabric a tool.

Update again :-)

Then I read a bit code of fabric and found that use fabric as a tool will call fabric.main.main which invokes fabric.main.load_fabfile to load tasks from the fabfile.

Since you use python main.py to run your script, fab tasks are not loaded even if you imported fabfile. So I add a bit code to you main.py:

docstring, callables, default = load_fabfile('fabfile.py')
state.commands.update(callables)

And now, execute('start') works exactly as you wanted.

OTHER TIPS

There is no need to use fabfile.py always. We can give any name to fabfile. Only we need to specify one parameter --fabfile.

Syntax:
fab --fabfile=<Your File Goes Here> function_name

Example:
fab --fabfile=test test_deploy
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top