Call another click command from a click command
<p>I want to use some useful functions as commands. For that I am testing the <code>click</code> library. I defined my three original functions then decorated as <code>click.command</code>:</p>

<pre><code>import click
import os, sys

@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=True)
def add_name(content, to_stdout=False):
    if not content:
        content = ''.join(sys.stdin.readlines())
    result = content + "\n\tadded name"
    if to_stdout is True:
        sys.stdout.writelines(result)
    return result


@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=True)
def add_surname(content, to_stdout=False):
    if not content:
        content = ''.join(sys.stdin.readlines())
    result = content + "\n\tadded surname"
    if to_stdout is True:
        sys.stdout.writelines(result)
    return result

@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=False)
def add_name_and_surname(content, to_stdout=False):
    result = add_surname(add_name(content))
    if to_stdout is True:
        sys.stdout.writelines(result)
    return result
</code></pre>

<p>This way I am able to generate the three commands <code>add_name</code>, <code>add_surname</code> and <code>add_name_and_surname</code> using a <code>setup.py</code> file and <code>pip install --editable .</code> Then I am able to pipe:</p>

<pre><code>$ echo "original content" | add_name | add_surname 
original content

    added name
    added surname
</code></pre>

<p>However there is one slight problem I need to solve, when composing with different click commands as functions:</p>

<pre><code>$echo "original content" | add_name_and_surname 
Usage: add_name_and_surname [OPTIONS] [CONTENT]

Error: Got unexpected extra arguments (r i g i n a l   c o n t e n t 
)
</code></pre>

<p>I have no clue why it does not work, I need this <code>add_name_and_surname</code> command to call <code>add_name</code> and <code>add_surname</code> not as command but as functions, else it defeats my original purpose of using functions as both  library functions and commands. </p>

<p>Due to the click decorators the functions can no longer be called just by specifying the arguments. 
The <a href="http://click.pocoo.org/6/api/#context" rel="nofollow">Context</a> class is your friend here, specifically:</p>

<ol>
<li>Context.invoke() - invokes another command with the arguments you supply</li>
<li>Context.forward() - fills in the arguments from the current command</li>
</ol>

<p>So your code for add_name_and_surname should look like:</p>

<pre><code>@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=False)
@click.pass_context
def add_name_and_surname(ctx, content, to_stdout=False):
    result = ctx.invoke(add_surname, content=ctx.forward(add_name))
    if to_stdout is True:
        sys.stdout.writelines(result)
    return result
</code></pre>

<p>Reference: 
<a href="http://click.pocoo.org/6/advanced/#invoking-other-commands" rel="nofollow">http://click.pocoo.org/6/advanced/#invoking-other-commands</a></p>

python command-line-arguments stdout piping python-click