A task runner for Python projects that enables task definition and execution through pyproject.toml configuration.
Configuration management system that parses pyproject.toml files and provides access to tasks, variables, and settings.
Central configuration manager that loads and parses pyproject.toml files.
class PyProject:
def __init__(self, base_dir: Path):
"""
Initialize PyProject with base directory.
Searches for pyproject.toml in base_dir and parent directories.
Args:
base_dir: Starting directory for pyproject.toml search
"""Access to all defined tasks with their configurations.
@property
def tasks(self) -> Dict[str, Task]:
"""
Dictionary of all defined tasks.
Returns:
Dict mapping task names to Task objects
Raises:
MissingTaskipyTasksSectionError: If [tool.taskipy.tasks] section missing
"""Access to all defined variables for task substitution.
@property
def variables(self) -> Dict[str, Variable]:
"""
Dictionary of all defined variables.
Returns:
Dict mapping variable names to Variable objects
Empty dict if no variables section exists
"""Access to global taskipy settings.
@property
def settings(self) -> dict:
"""
Dictionary of taskipy settings.
Returns:
Dict containing settings from [tool.taskipy.settings]
Empty dict if no settings section exists
"""Path to the directory containing the pyproject.toml file.
@property
def dirpath(self) -> Path:
"""
Path to directory containing pyproject.toml.
Returns:
Path object pointing to project root directory
"""Access to configured custom task runner.
@property
def runner(self) -> Optional[str]:
"""
Custom runner command if configured.
Returns:
Runner command string or None if not configured
Raises:
InvalidRunnerTypeError: If runner setting is not a string
"""from taskipy.pyproject import PyProject
from pathlib import Path
# Load project configuration
project = PyProject(Path('/path/to/project'))
# Access tasks
tasks = project.tasks
for name, task in tasks.items():
print(f"Task: {name}, Command: {task.command}")
# Access variables
variables = project.variables
for name, var in variables.items():
print(f"Variable: {name} = {var.value}")
# Access settings
settings = project.settings
print(f"Use vars globally: {settings.get('use_vars', False)}")# Nested project structure
# taskipy searches parent directories for pyproject.toml
project = PyProject(Path('/project/src/module')) # Finds /project/pyproject.toml
# Multi-project monorepo
# Each subproject can have its own pyproject.toml
project = PyProject(Path('/monorepo/service-a')) # Finds service-a/pyproject.tomlfrom taskipy.exceptions import (
MissingPyProjectFileError,
MalformedPyProjectError,
MissingTaskipyTasksSectionError
)
try:
project = PyProject(Path('/path/to/project'))
tasks = project.tasks
except MissingPyProjectFileError:
print("No pyproject.toml found in directory or parents")
except MalformedPyProjectError as e:
print(f"Invalid TOML syntax: {e.reason}")
except MissingTaskipyTasksSectionError:
print("No [tool.taskipy.tasks] section found")Tasks can be defined in two formats:
[tool.taskipy.tasks]
test = "python -m pytest"
lint = "pylint src tests"[tool.taskipy.tasks]
test = { cmd = "python -m pytest", help = "Run unit tests", cwd = ".", use_vars = true }
lint = { cmd = "pylint src tests", help = "Lint code with pylint" }Variables support both simple and recursive formats:
[tool.taskipy.variables]
src_dir = "src"
test_dir = "tests"[tool.taskipy.variables]
src_dir = "src"
package_dir = { var = "{src_dir}/mypackage", recursive = true }
test_path = { var = "{package_dir}/tests", recursive = true }Global settings that affect all tasks:
[tool.taskipy.settings]
use_vars = true # Enable variables globally
cwd = "." # Set global working directory
runner = "poetry run" # Prefix all commands with runnerPyProject automatically searches for pyproject.toml:
tomli library for robust TOML parsing[tool.taskipy.tasks][tool.taskipy.variables][tool.taskipy.settings]project/
├── pyproject.toml
├── src/
└── tests/monorepo/
├── pyproject.toml # Root configuration
├── service-a/
│ ├── pyproject.toml # Service-specific tasks
│ └── src/
└── service-b/
├── pyproject.toml # Service-specific tasks
└── src/project/
├── pyproject.toml
├── src/
│ └── mypackage/
│ └── submodule/ # taskipy works from any subdirectory
└── tests/Settings are applied with the following precedence:
Install with Tessl CLI
npx tessl i tessl/pypi-taskipy