Using Invoke as a task runner in Python

What is invoke?

Invoke is a Python (2.7 and 3.4+) task execution tool & library, drawing inspiration from various sources to arrive at a powerful & clean feature set. Taken from http://www.pyinvoke.org/

Invoke was split from the Fabric v1.X task running and ssh library. It is very powerful library that helps you add some sanity to your shell scripts and create cli programs on the fly.

The author of the library, Jeff Forcier also documents his entire design process of the library in the Github issues tracker, and discusses design choices for the api with inputs from the community.

Use Cases

The most common use case for invoke is for build and deployment automation, where the repeatable process needs to receive parameters, such as version numbers.

Another common use case is git tagging automation. You may want to streamline the way that your project is tagged, to ensure that it is in a consistent manner. You may also want to add some validation to your workflow, such as ensuring that version formats adhere to semantic versioning.

Quick Start

Installation

Using pip, it expose the inv command globally.

pip install invoke

Using a virtual environment with pipenv or poetry

poetry add invoke

pipenv install invoke

Create the tasks.py script

# /tasks.py
from invoke import task
@task
def build-my-project(c):
    # c refers to the terminal "context"
    print('building...')
    c.run('echo "hello world"')
    print('Success!')

Run your script

#  terminal
# The inv command is exposed upon installation of the package
$ inv buid-my-project
building...
hello world
Success!

Benefits

Maintainability and Audit-ability

Bash scripting has it's place, but what we're looking for is maintainability and audit-ability.

Some may argue that this would depend on code format and best practices, and I concede that this is true. However, I am of the opinion that python enforces certain conventions that aid ease of understanding scripts, making it easy for people of all backgrounds to read and audit it.

Manually Triggering Scripts

This is mostly a personal preference, but I find that inv my-task is easier to type than python ./path/to/my/script.py.

Leveraging the Python ecosystem

As you are basically executing python code, you can import whatever library you want.

Logical Flow

You are able to handle errors, change the code's logical execution based on external inputs (e.g. querying an API), and much more.

Using it as a library

Using invoke as a python library is a nice wrapper around the running of shell commands.

Can I...?

Can I use this in my CI/CD process?

Yes, of course! What I suggest that you do is to keep your general build scripts in python, which will allow you to trigger them easily. Then, in your CI/CD runner script, just trigger the build with pip install invoke and inv my-task.

Can I pass arguments to my task?

Yes, basically you are running functions with a command line interface. Numbers that are passed as arguments are also converted nicely to the correct data types.

For example:

# tasks.py
from invoke import task
@task
def my-echo-task(c, output):
    # This replaces the parenthesis with the parameter
    c.run("echo '{}'".format(output))
$ inv my-echo-task --output="testing"
testing

Can I use this with other languages?

Yes, you can. Polyglotism is always good, and you should always leverage the strengths of each language when you can. Python's strength is its clean syntax, simplicity, and extensive standard library.

For certain situations, it may be even preferable that you write it in python. For example, if you have npm scripts that need some logic, you can either write it in node, python, or a bash script (or whatever language you know). Due to the small standard libary of node, if you intend to have a script without external dependencies, it would be preferable to use a different language instead.

You should remember that invoke is just a task runner, and it is up to your imagination what you want to do with it.

Conclusion

I think that Invoke is an underrated and under-utilized library, and that more projects should leverage it.

TL;DR: Invoke is awesome, try it out as your task runner for projects.

© 2018-2019 Lee Tze Yiing. All rights reserved.Contact Me