A task runner for Python projects that enables task definition and execution through pyproject.toml configuration.
Task composition system supporting pre/post hooks, task chaining, and complex workflow orchestration through individual Task objects.
Individual task representation with metadata and configuration options.
class Task:
def __init__(self, task_name: str, task_toml_contents: object):
"""
Create Task from TOML configuration.
Args:
task_name: Name of the task
task_toml_contents: TOML content (string or dict)
"""Access to task metadata and configuration.
@property
def name(self) -> str:
"""Task name identifier."""
@property
def command(self) -> str:
"""Command to execute for this task."""
@property
def description(self) -> str:
"""Task description or help text."""
@property
def workdir(self) -> Optional[str]:
"""Working directory for task execution."""
@property
def use_vars(self) -> Optional[bool]:
"""Whether task uses variable substitution."""from taskipy.task import Task
# Create task from string
task = Task('test', 'python -m pytest')
print(f"Task: {task.name}, Command: {task.command}")
# Create task from dictionary
task_dict = {
'cmd': 'python -m pytest',
'help': 'Run unit tests',
'cwd': 'tests',
'use_vars': True
}
task = Task('test', task_dict)
print(f"Description: {task.description}")
print(f"Working directory: {task.workdir}")# Tasks are automatically composed by TaskRunner based on naming conventions
# No direct API needed - composition happens through configurationTasks with names starting with pre_ automatically run before the main task:
[tool.taskipy.tasks]
pre_test = "echo 'Setting up test environment'"
test = "python -m pytest"Execution order: pre_test → test
Tasks with names starting with post_ automatically run after the main task:
[tool.taskipy.tasks]
test = "python -m pytest"
post_test = "echo 'Cleaning up test artifacts'"Execution order: test → post_test
Full workflow with setup and cleanup:
[tool.taskipy.tasks]
pre_deploy = "echo 'Building application'"
deploy = "rsync -av dist/ server:/var/www/"
post_deploy = "echo 'Deployment complete'"Execution order: pre_deploy → deploy → post_deploy
Chain multiple tasks together using shell operators or task calls:
[tool.taskipy.tasks]
# Using shell operators
ci = "task lint && task test && task build"
# Using task dependencies
lint_pylint = "pylint src tests"
lint_mypy = "mypy src tests"
lint = "task lint_pylint && task lint_mypy"
# Complex workflows
full_check = "task lint && task test && task coverage && task docs"Use shell operators for conditional execution:
[tool.taskipy.tasks]
# Only run tests if lint passes
check = "task lint && task test"
# Run cleanup regardless of test result
test_with_cleanup = "task test; task cleanup"
# Run different commands based on environment
deploy = "if [ \"$ENV\" = \"prod\" ]; then task deploy_prod; else task deploy_dev; fi"Direct command specification:
[tool.taskipy.tasks]
test = "python -m pytest"
lint = "pylint src tests"
build = "python -m build"Full configuration with metadata:
[tool.taskipy.tasks]
test = {
cmd = "python -m pytest",
help = "Run unit tests with pytest",
cwd = "tests",
use_vars = true
}
lint = {
cmd = "pylint {src_path}",
help = "Lint code with pylint",
use_vars = true
}Set working directory for all tasks:
[tool.taskipy.settings]
cwd = "src"
[tool.taskipy.tasks]
test = "python -m pytest" # Runs from src/
lint = "pylint ." # Runs from src/Override working directory for specific tasks:
[tool.taskipy.tasks]
test = { cmd = "python -m pytest", cwd = "tests" }
lint = { cmd = "pylint .", cwd = "src" }
docs = { cmd = "sphinx-build . _build", cwd = "docs" }Tasks can use variable substitution when enabled:
[tool.taskipy.variables]
src_path = "src/mypackage"
test_path = "tests"
[tool.taskipy.tasks]
lint = { cmd = "pylint {src_path}", use_vars = true }
test = { cmd = "pytest {test_path}", use_vars = true }
# Or enable globally
[tool.taskipy.settings]
use_vars = true
[tool.taskipy.tasks]
lint = "pylint {src_path}"
test = "pytest {test_path}"[tool.taskipy.tasks]
# Individual steps
clean = "rm -rf dist/ build/"
lint = "pylint src tests"
test = "python -m pytest"
build = "python -m build"
upload = "twine upload dist/*"
# Composed workflows
pre_build = "task clean && task lint && task test"
build_and_upload = "task build && task upload"
full_release = "task pre_build && task build_and_upload"[tool.taskipy.tasks]
# Development tasks
format = "black src tests"
lint = "pylint src tests"
type_check = "mypy src"
test = "pytest tests/"
coverage = "pytest --cov=src tests/"
# Composed checks
check_code = "task format && task lint && task type_check"
check_all = "task check_code && task test && task coverage"
# Pre-commit hook
pre_commit = "task check_all"[tool.taskipy.tasks]
# Base tasks
test_unit = "pytest tests/unit"
test_integration = "pytest tests/integration"
test_e2e = "pytest tests/e2e"
# Environment compositions
test_dev = "task test_unit && task test_integration"
test_ci = "task test_unit && task test_integration && task test_e2e"
test_all = "task test_ci"[tool.taskipy.tasks]
# Ensure cleanup runs even if test fails
test_with_cleanup = "task test; task cleanup"
# Continue on lint failure but still run tests
flexible_check = "task lint || true; task test"
# Conditional cleanup based on test result
smart_test = "task test && task success_cleanup || task failure_cleanup"Provide descriptive help for tasks:
[tool.taskipy.tasks]
test = {
cmd = "python -m pytest",
help = "Run unit tests with coverage reporting"
}
lint = {
cmd = "pylint src tests",
help = "Check code style and potential errors"
}Use help text to document complex workflows:
[tool.taskipy.tasks]
deploy = {
cmd = "task build && task upload && task notify",
help = "Full deployment: build, upload to server, notify team"
}Install with Tessl CLI
npx tessl i tessl/pypi-taskipy