CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-invoke

Pythonic task execution library for managing shell-oriented subprocesses and organizing executable Python code into CLI-invokable tasks

Overall
score

96%

Overview
Eval results
Files

task-execution.mddocs/

Task Definition and Execution

Task definition and execution forms the core of Invoke's functionality, allowing Python functions to be decorated and invoked from the command line with automatic argument parsing, help generation, and execution management.

Capabilities

Task Decorator

The primary decorator for converting Python functions into CLI-invokable tasks with rich metadata and argument handling.

def task(*args, **kwargs):
    """
    Decorator for converting functions into Task objects.
    
    Parameters:
    - name (str, optional): Task name (defaults to function name)
    - aliases (tuple, optional): Alternative names for the task
    - positional (list, optional): Arguments that should be positional
    - optional (list, optional): Arguments that should be optional
    - default (bool): Whether this task is the collection's default
    - auto_shortflags (bool): Auto-generate short flags for arguments
    - help (dict, optional): Help text for task and arguments
    - pre (list, optional): Tasks to run before this task
    - post (list, optional): Tasks to run after this task  
    - iterable (list, optional): Arguments that accept multiple values
    - incrementable (list, optional): Arguments that can be repeated to increment
    
    Returns:
    Task: Decorated task object
    """

Usage example:

from invoke import task

@task
def hello(ctx, name="World"):
    """Say hello to someone."""
    print(f"Hello {name}!")

@task(help={'env': 'Target environment'})
def deploy(ctx, env='staging'):
    """Deploy to specified environment.""" 
    ctx.run(f"deploy.sh {env}")

@task(aliases=['ls'])
def list_files(ctx):
    """List files in current directory."""
    ctx.run("ls -la")

Task Class

Core task representation containing metadata, argument specifications, and execution state.

class Task:
    """
    Core task class wrapping a callable with metadata and argument handling.
    
    Attributes:
    - name (str): Task name
    - called (bool): Whether task has been called
    - times_called (int): Number of times task has been invoked
    - body (callable): Underlying Python function
    - aliases (tuple): Alternative task names
    - positional (list): Positional argument names
    - optional (list): Optional argument names  
    - default (bool): Whether this is the default task
    - auto_shortflags (bool): Auto-generate short flags
    - help (dict): Help text mapping
    - pre (list): Pre-execution tasks
    - post (list): Post-execution tasks
    - iterable (list): Multi-value arguments
    - incrementable (list): Incrementable arguments
    """
    
    def __init__(self, body, name=None, aliases=None, positional=None, optional=None, default=False, auto_shortflags=True, help=None, pre=None, post=None, iterable=None, incrementable=None):
        """
        Initialize a Task object.
        
        Parameters match the task decorator parameters.
        """
    
    def argspec(self, body):
        """
        Get argument specification from function signature.
        
        Parameters:
        - body (callable): Function to inspect
        
        Returns:
        argspec: Function argument specification
        """
    
    def fill_implicit_positionals(self, args):
        """
        Fill in positional arguments not explicitly marked.
        
        Parameters:
        - args (list): Existing positional arguments
        
        Returns:
        list: Updated positional arguments
        """
        
    def arg_opts(self, name, default, taken_names):
        """
        Generate argument parsing options for a parameter.
        
        Parameters:
        - name (str): Parameter name
        - default: Parameter default value
        - taken_names (set): Already used argument names
        
        Returns:
        dict: Argument parsing options
        """
    
    def get_arguments(self):
        """
        Generate Argument objects for all task parameters.
        
        Returns:
        list: List of Argument objects for CLI parsing
        """

Call Class

Represents a specific invocation of a task with arguments and execution context.

class Call:
    """
    Task execution call with specific arguments and context.
    
    Attributes:
    - task (Task): Task being called
    - args (tuple): Positional arguments
    - kwargs (dict): Keyword arguments
    """
    
    def __init__(self, task, args=None, kwargs=None):
        """
        Initialize a Call object.
        
        Parameters:
        - task (Task): Task to call
        - args (tuple, optional): Positional arguments
        - kwargs (dict, optional): Keyword arguments
        """
    
    def make_context(self, config):
        """
        Create execution context for this call.
        
        Parameters:
        - config (Config): Configuration object
        
        Returns:
        Context: Execution context with config and call data
        """
    
    def clone_data(self, **kwargs):
        """
        Clone call data with optional overrides.
        
        Parameters:
        - **kwargs: Data to override
        
        Returns:
        dict: Cloned call data
        """
    
    def clone(self, into=None, **kwargs):
        """
        Clone this call with optional modifications.
        
        Parameters:
        - into (type, optional): Class to clone into
        - **kwargs: Attributes to override
        
        Returns:
        Call: Cloned call object
        """
    
    def __getattr__(self, name):
        """Delegate attribute access to wrapped task."""
    
    def __eq__(self, other):
        """Test equality with another call."""
    
    def __hash__(self):
        """Generate hash for call object."""

Call Factory Function

Convenience function for creating Call objects.

def call(task, *args, **kwargs):
    """
    Create a Call object for executing a task with arguments.
    
    Parameters:
    - task (Task): Task to call
    - *args: Positional arguments for task
    - **kwargs: Keyword arguments for task
    
    Returns:
    Call: Call object ready for execution
    """

Usage example:

from invoke import task, call

@task
def deploy(ctx, env='staging'):
    ctx.run(f"deploy.sh {env}")

# Create call objects
staging_deploy = call(deploy, env='staging')  
prod_deploy = call(deploy, env='production')

Usage Examples

Basic Task Definition

from invoke import task

@task
def clean(ctx):
    """Clean build artifacts."""
    ctx.run("rm -rf build/ dist/ *.egg-info/")

@task
def build(ctx, docs=False):
    """Build the project."""
    ctx.run("python setup.py build")
    if docs:
        ctx.run("sphinx-build docs docs/_build")

@task(clean)  # Pre-task dependency
def test(ctx):
    """Run test suite."""
    ctx.run("python -m pytest")

Advanced Task Configuration

from invoke import task

@task(
    aliases=['serve'],
    help={
        'port': 'Port to serve on (default: 8000)',
        'host': 'Host to bind to (default: localhost)'
    },
    iterable=['exclude'],
    incrementable=['verbose']
)
def runserver(ctx, port=8000, host='localhost', exclude=None, verbose=0):
    """Run development server."""
    excludes = exclude or []
    verbosity = '-' + 'v' * verbose if verbose else ''
    
    exclude_args = ' '.join(f'--exclude {ex}' for ex in excludes)
    ctx.run(f"python manage.py runserver {host}:{port} {verbosity} {exclude_args}")

# Usage from CLI:
# invoke runserver --port 3000 --exclude logs --exclude temp -vv

Task Dependencies

from invoke import task

@task
def setup_env(ctx):
    """Set up virtual environment."""
    ctx.run("python -m venv venv")
    ctx.run("venv/bin/pip install -r requirements.txt")

@task
def migrate(ctx):
    """Run database migrations."""
    ctx.run("python manage.py migrate")

@task(pre=[setup_env, migrate])
def deploy(ctx):
    """Deploy application (runs setup and migration first)."""
    ctx.run("python manage.py collectstatic --noinput")
    ctx.run("systemctl restart myapp")

Install with Tessl CLI

npx tessl i tessl/pypi-invoke

docs

cli-parsing.md

collections.md

configuration.md

index.md

subprocess-runners.md

task-execution.md

watchers.md

tile.json