Fabric: "No idea what *something* is!" after running fabric2

Created on 16 Aug 2018  ·  18Comments  ·  Source: fabric/fabric

I am new to fabric and having trouble getting it to work. I installed it via pip3 first when I tried to run it I was getting Command 'fab' not found, I eventually found it in /home/me/.local/bin/fab2.

Is this the correct place?

Second whenever I run it like so

/home/me/.local/bin/fab2 version

I get

(2, 3, 1)
2.3.1
No idea what 'version' is!
import fabric
if hasattr(fabric, '__version__'):
    # For fabric2
    print(fabric.__version_info__)
    print(fabric.__version__)   # for a version tuple
else:
    # for fabric1
    from fabric.api import *
    print(env.version)

Is /home/me/.local/bin/fab2 the correct location?
What is 'No idea what 'version' is!' why does it show up?

Most helpful comment

@ajmcateer, I had this problem as well. The issue is that thew new fabric task method (as discussed here - http://docs.fabfile.org/en/1.14/usage/tasks.html) is to use the @task decorator. The equivalent "Hello World' example is:

from fabric import task

@task
def hello(ctx):
  print("Hello World")

Running 'fab hello' yields the expected output.

All 18 comments

It's looking for a task function named "version" in a fabfile and not finding one. fab --version does what you want there.

$HOME/.local/bin/ is where pip installs executable "entrypoints" when you pip install --user ... - you could add $HOME/.local/bin to your PATH (e.g. in your ~/.bash_profile or ~/.bashrc). If you did sudo pip install Fabric (without --user) it would put the executable entrypoint in /usr/local/bin/ which is probably in your PATH already. Or you can probably python -m fabric <fab args> instead.

Hi thank you fabric --version worked great

I changed the script to look like this

def hello():
    print("Hello world!")

I am still getting 'No idea what 'hello' is!'

Is there a tutorial for fabric 2 I am having a hell of a time getting anything to work in it. I found the tutorial for fabric 1.14 but that isn't really helpful at the moment since none of the imports work. I am assuming fabric 2 handles it differently.

if I run with fab or fab2 I get the same error

I have fabric in /home/me/fabric

@ajmcateer, I had this problem as well. The issue is that thew new fabric task method (as discussed here - http://docs.fabfile.org/en/1.14/usage/tasks.html) is to use the @task decorator. The equivalent "Hello World' example is:

from fabric import task

@task
def hello(ctx):
  print("Hello World")

Running 'fab hello' yields the expected output.

I have both from fabric import task as well as @task decorator.
Still I'm getting 'No idea ..' error.

Additional details :

$ fab --version 
Fabric 2.3.1
Paramiko 2.4.1
Invoke 1.1.1

$ python --version
Python 3.6.2

$ more tasks.py
#!/usr/bin/env python

from fabric import task

@task
def build(c):
    import pdb; pdb.set_trace()
    print("Building!")

$ fab build -f tasks.py
No idea what 'build' is!

@mandravaze, I can confirm it worked for me, though I have task in fabfile.py (it think this is the problem in your env) and I use following line to call
$fab build

it think this is the problem in your env

How I can troubleshoot ? What additional data would you like ?

What files do you have in this location? I think build() should be in the fabfile.py, if it is there, perhaps your fab picks up wrong file...

@mandarvaze in your command fab build -f tasks.py there are multiple confusions.

  • arguments for fab itself must come before the first taskname, like fab -f tasks.py build
  • the -f flag is for a config file, not for a tasks collection, that's the -cflag, like fab -c tasks build (no ".py" extension!)
  • For inv (invoke), if the file with the tasks is tasks.py in the current directory, you don't need to specify it. For fab (fabric), if the file with the tasks is fabfile.py in the current directory, you don't need to specify it.

@ploxiln fab -c tasks build works. 👍
Thanks.

@ajmcateer, I had this problem as well. The issue is that thew new fabric task method (as discussed here - http://docs.fabfile.org/en/1.14/usage/tasks.html) is to use the @task decorator. The equivalent "Hello World' example is:

from fabric import task

@task
def hello(ctx):
  print("Hello World")

Running 'fab hello' yields the expected output.

sorry for stupid question, but why do we need 'ctx' arg? what is it?

in fabric 2 you need this ctx to actually run commands on the correct system, e.g. ctx.run("hostname")

If your issue is that you receive this error for a task argument, it may be that you are not passing the argument in its correct format, but as how you have your task named.

fab mytask --task-name value

not

fab mytask --task_name value

I realize this isn't spot on the issue, but since I ended up here, I'll leave this for anybody else who has my same issue.

in fabric 2 you need this ctx to actually run commands on the correct system, e.g. ctx.run("hostname")

First of all, thanks for the info!!

Unfortunately, I have to say Fabric 2 is completely obtuse. The logic of 2.x is very counterintuitive and there really don't seem to be very many good basic tutorials on how to use it. For example, Maybe I am missing something, but look at the logic of 1.x and the quality of this 1.x tutorial: https://docs.fabfile.org/en/1.14/tutorial.html. Then look around for an equivalent tutorial for 2.x ....

No wonder there is an unofficial port of 1.x and they are - quite boldy - calling it 3.x

Just a general FYI that _none_ of this detail around needing the @task decorator, having to pass a context object etc. are present in the "Overview and Tutorial" section of the public documentation for Fabric: https://docs.fabfile.org/en/1.8/tutorial.html

I was a heavy user of Fabric 1 and naively assumed that this walkthrough was teaching me new semantics for Fabric 2 before I found this issue ticket. It could really discourage adoption as the docs are essentially misleading for people onboarding.

I'm not sure how you ended up on that page, you should be looking at https://docs.fabfile.org/en/2.5/getting-started.html

Thanks for that! Perhaps it would help future travelers to throw a fat "DEPRECATED" header on the 1 series docs. I'm pretty sure I navigated to this either from a top google result or the official fabric website docs, and in either case I think while the former isn't sort of something the Fabric team can control, I suspect many potential adopters are incurring this frustration and might benefit from being alerted to the need to find the up-to-date docs (the official Python hosted docs follow a similar pattern iirc).

It could really discourage adoption as the docs are essentially misleading for people onboarding.

Brand new user of Fabric. I googled "Fabric Python", and clicked the link that said "Overview and Tutorial". Yes, I found this really confusing and am pretty surprised I was able to go the wrong way so early in the process.

I suspect many potential adopters are incurring this frustration and might benefit from being alerted to the need to find the up-to-date docs (the official Python hosted docs follow a similar pattern iirc).

Yes.

Also, note that this is the result page:

Screenshot from 2020-11-16 22-43-32

Those indented links can be configured if you control the domain. Maybe it's possible to purge 1.x stuff from the search results on top of adding a "DEPRECATED" header on them.

I just stumbled on this one and finally able to fix it. Nothing is wrong with the fabric.
Here's what I did.

╰─$ fab --version
Fabric 2.5.0
Paramiko 2.7.2
Invoke 1.4.1

In my fabfile.py:

from fabric.tasks import task

@task
def test(ctx, title):
    print("ctx:", ctx)
    print("title:", title)

If I just run the task:

╰─$ fab test                                                                                                                                                                                                                      
'test' did not receive required positional arguments: 'title'

This means it's expecting the title as an argument.
So, pass the argument:

fab test title="hello world"

Output:

ctx: <your current context. Don't worry about it>
title: title=hello world

But be aware that the argument passed will be a string. Be sure to split with =.

For example:

@task
def test(ctx, title):
    print("ctx:", ctx)
    print("title type:", type(title))
    print("title:", title)
    print("title value:", title.split("=")[1])

run:

fab test title="hello world"

Output:

ctx: ...
title type: <class 'str'>
title: title=hello world
title value: hello world

Was this page helpful?
0 / 5 - 0 ratings