Skip to main content

tasks runner for python projects

Project description

taskipy2

The complementary task runner for python.

taskipy2 is a continuation fork of taskipy.

Overview

pypi pypi-downloads builds.sr.ht status

Every development pipeline has tasks, such as test, lint or publish. With taskipy, you can define those tasks in one file and run them with a simple command.

For instance, instead of running the following command:

python -m unittest tests/test_*.py

You can create a task called test and simply run (in your virtual environment):

task test

If you're using a tool like poetry or uv, you could run:

poetry run task test
# or
uv run task test

In addition, you can compose tasks and group them together, and also create dependencies between them.

This project is heavily inspired by npm's run command.

Requirements

Python 3.6 or newer.

Your project directory should include a valid pyproject.toml file, as specified in PEP-518.

Usage

Installation

To install taskipy via pip, run:

pip install taskipy2

Poetry

poetry add --group dev taskipy2

uv

uv add --dev taskipy

Running Tasks

Head into your project's directory (don't forget to activate virtualenv if you're using one), and run the following command:

task TASK

Where TASK is the name of your task.

poetry add --group dev taskipy2

Adding Tasks

In your pyproject.toml file, add a new section called [tool.taskipy.tasks].

The section is a key-value map, from the names of the task to the actual command that should be run in the shell.

There are two ways to define tasks. The easy way is to simply write the command down as a string:

pyproject.toml

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
lint = "pylint tests taskipy"

Alternatively, you can define tasks more explicitly by declaring both the command and a helpful description using an inline table:

pyproject.toml

[tool.taskipy.tasks]
test = { cmd = "python -m unittest tests/test_*.py", help = "runs all unit tests" }
lint = { cmd = "pylint tests taskipy", help = "confirms code style using pylint" } 

The explicit notation is more verbose, but provides better context to anyone who uses the task.

Running Tasks

In order to run a task, run the following command in your terminal:

$ poetry run task test

You can also list all existing tasks by running the following:

$ poetry run task --list
test                python -m unittest tests/test_*.py
lint                pylint tests taskipy

If you declared your task explicitly, you will see the description of the task by the side of the task's name:

$ poetry run task --list
test                runs all unit tests
lint                confirms code style using pylint

Passing Command Line Args to Tasks

If you want to pass command line arguments to tasks (positional or named), simply append them to the end of the task command.

For example, running the above task like this:

poetry run task test -h

Is equivalent to running:

python -m unittest tests/test_*.py -h

And will show unittest's help instead of actually running it.

⚠️ Note: if you are using pre \ post hooks, do notice that arguments are not passed to them, only to the task itself.

Composing Tasks

Grouping Subtasks Together

Some tasks are composed of multiple sub-tasks. Instead of writing plain shell commands and stringing them together, you can break them down into multiple sub-tasks:

[tool.taskipy.tasks]
lint_pylint = "pylint tests taskipy"
lint_mypy = "mypy tests taskipy"

And then create a composite task:

[tool.taskipy.tasks]
lint = "task lint_pylint && task lint_mypy"
lint_pylint = "pylint tests taskipy"
lint_mypy = "mypy tests taskipy"

Pre Task Hook

Tasks might also depend on one another. For example, tests might require some binaries to be built. Take the two following commands, for instance:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
build = "make ."

You could make tests depend on building, by using the pre-task hook:

[tool.taskipy.tasks]
pre_test = "task build"
test = "python -m unittest tests/test_*.py"
build = "make ."

The pre-task hook looks for pre_<task_name> task for a given task_name. It will run it before running the task itself. If the pre-task fails, then taskipy will exit without running the task itself.

Post Task Hook

From time to time, you might want to run a task in conjunction with another. For example, you might want to run linting after a successful test run. Take the two following commands, for instance:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
lint = "pylint tests taskipy"

You could make tests trigger linting, by using the post-task hook:

[tool.taskipy.tasks]
test = "python -m unittest tests/test_*.py"
post_test = "task lint"
lint = "pylint tests taskipy"

The post-task hook looks for post_<task_name> task for a given task_name. It will run it after running the task itself. If the task failed, then taskipy will not run the post-task hook.

Using Variables

In some cases, you might find yourself passing the same arguments over and over again. Let us take a look at the following tasks:

[tool.taskipy.tasks]
lint = "pylint path/to/my_module"
black = "black path/to/my_module"

As you can see, we provide the same path argument to both pylint and black.

In order to encourage DRY and improve your ability to change these values later on, taskipy actually lets you declare and reuse variables in your tasks:

[tool.taskipy.variables]
path = "path/to/my_module"

[tool.taskipy.tasks]
lint = { cmd = "pylint {path}", use_vars = true }
black = { cmd = "pylint {path}", use_vars = true }

We have made the following changes to our configuration:

  1. We declared variables under tool.taskipy.variables
  2. We flagged the relevant task using use_vars to note that they should use the variables
  3. We replaced the repeating path with a {path} variable

String Formatting

The formatting of the task commands uses python's own string.format method, and therefore supports everything that python's formatted string literals let you do.

Always Use Variables

Using variables is opt-in, which means that by default commands do not use them, and you will have to turn them on a task to task basis.

If you want to turn on use_vars globally, all you need to do is to declare that under taskipy's settings table:

[tool.taskipy.settings]
use_vars = true

[tool.taskipy.variables]
path = "path/to/my_module"

[tool.taskipy.tasks]
lint = "pylint {path}"
black = "black {path}"

Recursive Variables

If we want to use variables within other variables, we can utilize recursive variables. By default, variables are not recursive, but we can specify a variable to be recursive by setting the recursive key to true.

[tool.taskipy.settings]
use_vars = true

[tool.taskipy.variables]
src_dir = "src"
package_dir = { var = "{src_dir}/package", recursive = true }

[tool.taskipy.tasks]
echo = "echo {package_dir}"

In this example, we could run task echo and we would then see src/package.

Working directory

By default, all tasks run from the directory where they are called. This makes possible to change folder and run flexible tasks depending on the current folder.

However, some tasks may need to always run in the same working directory, regardless from where they are called.

If you want tasks to always run relative to a specific path, you can use the "cwd" setting to define a current working directory of the task relative to the root of the project (where the pyproject.toml file is):

[tool.taskipy.tasks]
echo = { cmd = "python -c \"import os; print(os.getcwd())\"" , cwd = "."}

In this example, running task echo will print the directory path of the file pyproject.toml regardless of the folder that you call this task.

If you want to define cwd globally (setting all tasks to always run from the same working directory) you just need to declare that under taskipy's settings table:

[tool.taskipy.settings]
cwd = "."

Advanced Use Cases

If you have a more specific use case, you might not be the first to run into it! Head over to the ADVANCED_FEATURES doc, and look it up.

Contributing

All kinds of contributions are welcome! Feel free to request features, report bugs, or contribute your code via patches.

The taskipy2 project is maintained by Eugene Triguba, and it uses an email-based workflow.

The following mailing lists are used:

  • taskipy2-discuss
    • Mailing list for end-user discussion and questions related to the taskipy2 project. If you have a feature request, want to talk about a issue you're having, etc., go here.
  • taskipy2-devel
    • Mailing list for development discussion and patches related to the taskipy2 project. For help sending patches via email to this list, please consult git-send-email.io.
  • taskipy2-announce
    • Low-volume mailing list for announcements related to the taskipy2 project. Used primarily for new release announcements.

Furthermore, once issues or feature requests are discussed and triaged via taskipy2-discuss, they make their way to the official project tracker:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

taskipy2-1.16.1.tar.gz (61.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

taskipy2-1.16.1-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file taskipy2-1.16.1.tar.gz.

File metadata

  • Download URL: taskipy2-1.16.1.tar.gz
  • Upload date:
  • Size: 61.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.3","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for taskipy2-1.16.1.tar.gz
Algorithm Hash digest
SHA256 1e215c7326d44aaa2bfb0d38886a9cb8d48afd2379542712c03197e9985850a8
MD5 e08bbd95acb2d24118b2139b7509bfdb
BLAKE2b-256 1daeb23031e8a76e7a522b791d9563f4e2e06ed267a6e0df30f024acd5409553

See more details on using hashes here.

File details

Details for the file taskipy2-1.16.1-py3-none-any.whl.

File metadata

  • Download URL: taskipy2-1.16.1-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.3","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for taskipy2-1.16.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f05b880c2f66b8c98d9263b6712d1d68fef6b143b5c00ff11614aa27c70fbd1d
MD5 1f78b1843fbdd93152c10901f058ea48
BLAKE2b-256 4958484dbcdc47b3a372d79b6d925d244605593017f2fbe7e7649981d5b706d6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page