In Fabric, how can I execute tasks from another python file?
Asked Answered
E

2

6

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

Engaging answered 12/5, 2014 at 9:28 Comment(2)
Run fab -h, it gives: -f PATH, --fabfile=PATH.Tetrafluoroethylene
But I'm trying to use the tasks from another python script, not using the fab tool :sEngaging
T
8

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.

Tetrafluoroethylene answered 12/5, 2014 at 10:33 Comment(4)
That works, but I need to use the task name, as it is going to be passed as an argument. As specified here: docs.fabfile.org/en/latest/api/core/… it should work using the task nameEngaging
Yeah, that works! I was so decided to use the task name that I didn't think of that solution. Thank you!Engaging
@Engaging Another solution added.Tetrafluoroethylene
@Garinoth, how to pass arguments to fabfile.Pneumato
D
1

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
Devries answered 27/2, 2019 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.