“Rituals” is a task library for Invoke
that keeps the most common tasks you always need out of your project,
and makes them centrally maintained. This leaves your
and to the point, with only things specific to the project at hand.
The following lists the common task implementations that the
rituals.easy module offers. See below
on how to integrate them into your
help– Default task, when invoked with no task names.
clean– Perform house-cleaning.
build– Build the project.
docs– Build the documentation.
test– Perform standard unittests.
check– Perform source code checks.
release.bump– Bump a development version.
release.dist– Distribute the project.
release.prep– Prepare for a release.
- … and many more, see
inv -lfor a complete list.
The guiding principle for these tasks is to strictly separate low-level
tasks for building and installing (via
setup.py) from high-level
convenience tasks a developer uses (via
invoke). Invoke tasks can
use Setuptools ones as building blocks, but never the other way ‘round –
this avoids any bootstrapping headaches during package installations.
inv -h ‹task› as usual to get details on the options of these
The Tasks Reference explains them in more detail.
Look at the modules in
if you want to know every nuance of what these tasks do.
The easiest way to get a working project using
rituals is the
py-generic-project cookiecutter archetype, which is tightly
integrated with the tasks defined here.
That way you have a working project skeleton within minutes that is fully equipped, with all aspects of building, testing, quality checks, continuous integration, documentation, and releasing covered.
Adding Rituals to Your Project¶
First of all, include
rituals as a dependency in your
or a similar file, to get a release from PyPI.
To refer to the current GitHub
master branch instead, use a
requirement like this:
Then at the start of your
tasks.py, use the following statement to define
all tasks that are considered standard:
from rituals.easy import *
This works by defining the
namespace identifier containing Ritual’s default tasks.
Note that it also defines Invoke’s
and some other common helpers assembled in
Rituals’ own tasks.py can serve as an example.
Of course, you may also do more selective imports, or build your own Invoke namespaces with the specific tasks you need.
project = dict( # this would usually be a setup(…) call name='…', … ) if __name__ == '__main__': setup(**project)
The Root Namespace¶
The tasks useful for any (Python) project are organized in a root namespace.
When you use the
from rituals.easy import * statement, that also imports
this root namespace. By convention of Invoke, when the identifier
is defined, that one is taken instead of constructing one automatically from
all defined tasks.
It contains some fundamentals like
clean, and nested namespaces handling
specific topics. Examples of nested namespaces are
release. See Tasks Reference for a complete list.
The root namespace has
help as the default task, and
most nested namespaces also have a default with the most commonly performed
action. These default tasks are automatically aliased to the name of the
namespace, so for example
docs.sphinx can also be called as
Adding Local Task Definitions¶
Having an explicit root namespace
means that within
tasks.py, you need to register your own tasks
add_task method, if you want them to be
available as top-level names:
@task def my_own_task(ctx): """Something project-specific.""" … namespace.add_task(my_own_task)
Rituals’ own tasks.py uses this to add some local tasks.
Another strategy is to add them in bulk, so when you write a new task you cannot forget to make it visible:
# Register local tasks in root namespace from invoke import Task for _task in globals().values(): if isinstance(_task, Task) and _task.body.__module__ == __name__: namespace.add_task(_task)
Add the above snippet to the end of your
and every local task definition gets added to the root namespace.
Constructing Your Own Namespace¶
When you want to have more control, you can exclude the
identifier from the import and instead define your own.
This example taken from the
tasks.py of py-generic-project
shows how it’s done:
from rituals.easy import task, Collection from rituals.acts.documentation import namespace as _docs … namespace = Collection.from_module(sys.modules[__name__], name='') namespace.add_collection(_docs)
Note that the
name='' makes this a root namespace.
If you need to be even more selective, import individual tasks from modules
rituals.acts and add them to your namespaces.
Change default project layout¶
By default, sources are expected in
src/‹packagename› and tests in
You can change this by calling one of the following functions, directly
after the import from
config.set_maven_layout()– Changes locations to
config.set_flat_layout()– Changes locations to
Change default project configuration¶
If you want to override the configuration defaults of various tasks,
without using environment variables, add an
invoke.yaml file in
the same directory where your
tasks.py is located
– usually the project root directory.
This example makes Sphinx (as called by the default
place generated files in the top-level
build directory instead
of a sub-directory in
rituals: docs: build: ../build/_html
See Configuration Reference for a list of possible options.