CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-xonsh

Python-powered shell providing superset of Python with shell primitives for cross-platform command execution and automation.

Overview
Eval results
Files

api-package.mddocs/

API Package

Overview

The xonsh.api package provides a pure Python interface to xonsh functionality, designed for use by external tools and scripts that need xonsh capabilities without running a full xonsh shell. This package includes subprocess wrappers and OS utilities that leverage xonsh's enhanced command execution.

Subprocess Module

Enhanced Subprocess Functions

from xonsh.api.subprocess import run, check_call, check_output

def run(cmd: list[str], cwd: str = None, check: bool = False) -> object:
    """Drop-in replacement for subprocess.run with xonsh enhancements.
    
    Parameters
    ----------
    cmd : list[str]
        Command and arguments to execute
    cwd : str, optional
        Working directory for command execution
    check : bool, default False
        Whether to raise exception on non-zero return code
        
    Returns
    -------
    object
        Process object with stdout, stderr, returncode attributes
        
    Examples
    --------
    # Basic command execution
    result = run(['ls', '-la'])
    print(f"Return code: {result.returncode}")
    
    # With working directory
    result = run(['git', 'status'], cwd='/path/to/repo')
    
    # With error checking
    result = run(['make', 'build'], check=True)  # Raises on failure
    """

def check_call(cmd: list[str], cwd: str = None) -> int:
    """Execute command and raise exception on failure.
    
    Parameters
    ----------
    cmd : list[str]
        Command and arguments to execute
    cwd : str, optional
        Working directory for command execution
        
    Returns
    -------
    int
        Return code (always 0 if successful)
        
    Raises
    ------
    CalledProcessError
        If command returns non-zero exit code
        
    Examples
    --------
    # Successful command
    check_call(['mkdir', '-p', '/tmp/test'])
    
    # Command with working directory
    check_call(['npm', 'install'], cwd='/path/to/project')
    
    # Will raise exception if git command fails
    check_call(['git', 'push', 'origin', 'main'])
    """

def check_output(cmd: list[str], cwd: str = None) -> bytes:
    """Execute command and return output, raising exception on failure.
    
    Parameters
    ----------
    cmd : list[str]
        Command and arguments to execute
    cwd : str, optional
        Working directory for command execution
        
    Returns
    -------
    bytes
        Command output as bytes
        
    Raises
    ------
    CalledProcessError
        If command returns non-zero exit code
        
    Examples
    --------
    # Get command output
    output = check_output(['git', 'rev-parse', 'HEAD'])
    commit_hash = output.decode().strip()
    
    # Command with working directory
    files = check_output(['ls', '-1'], cwd='/tmp')
    file_list = files.decode().strip().split('\n')
    
    # Will raise exception if command fails
    version = check_output(['python', '--version'])
    """

OS Module

Enhanced OS Utilities

from xonsh.api.os import rmtree, indir

def rmtree(dirname: str, force: bool = False) -> None:
    """Remove directory tree with cross-platform compatibility.
    
    Handles read-only files on Windows that standard rmtree cannot remove.
    Uses xonsh subprocess execution for reliable cross-platform operation.
    
    Parameters
    ----------
    dirname : str
        Directory path to remove
    force : bool, default False
        If True, force removal (adds 'f' flag on Unix systems)
        
    Examples
    --------
    # Basic directory removal
    rmtree('/tmp/test_dir')
    
    # Force removal (useful for git repositories with read-only files)
    rmtree('/tmp/repo_clone', force=True)
    
    # Windows-compatible removal
    import sys
    if sys.platform == 'win32':
        rmtree('C:\\temp\\test')  # Uses rmdir /S/Q
    else:
        rmtree('/tmp/test')       # Uses rm -r
    """

def indir(dirname: str):
    """Context manager for temporary directory changes.
    
    Alias to xonsh.dirstack.with_pushd for API consistency.
    Changes to specified directory and restores original directory on exit.
    
    Parameters
    ----------
    dirname : str
        Directory to change to temporarily
        
    Returns
    -------
    context manager
        Context manager for directory change
        
    Examples
    --------
    import os
    
    # Temporary directory change
    print(f"Original: {os.getcwd()}")
    with indir('/tmp'):
        print(f"Inside context: {os.getcwd()}")  # /tmp
        # Do work in /tmp
    print(f"Restored: {os.getcwd()}")  # Original directory
    
    # Nested directory changes
    with indir('/var'):
        print(f"First level: {os.getcwd()}")
        with indir('log'):
            print(f"Nested: {os.getcwd()}")  # /var/log
        print(f"Back to first: {os.getcwd()}")  # /var
    """

# Direct alias for convenience
from xonsh.dirstack import with_pushd
indir = with_pushd  # Context manager for directory changes

Integration Patterns

Using API in External Scripts

#!/usr/bin/env python3
"""Example external script using xonsh API."""

from xonsh.api.subprocess import run, check_output
from xonsh.api.os import indir, rmtree

def deploy_project(project_path: str, deploy_path: str) -> bool:
    """Deploy project using xonsh API functions.
    
    Parameters
    ----------
    project_path : str
        Source project directory
    deploy_path : str
        Deployment target directory
        
    Returns
    -------
    bool
        True if deployment successful
    """
    try:
        # Clean deployment directory
        rmtree(deploy_path, force=True)
        
        # Build project
        with indir(project_path):
            result = run(['npm', 'run', 'build'], check=True)
            
            # Get build info
            build_info = check_output(['npm', 'run', 'build:info'])
            print(f"Build info: {build_info.decode().strip()}")
        
        # Copy build artifacts
        result = run(['cp', '-r', f'{project_path}/dist', deploy_path])
        
        return result.returncode == 0
        
    except Exception as e:
        print(f"Deployment failed: {e}")
        return False

# Usage
if __name__ == '__main__':
    success = deploy_project('/src/myapp', '/var/www/myapp')
    print(f"Deployment {'succeeded' if success else 'failed'}")

Library Integration

"""Library that uses xonsh API for enhanced subprocess operations."""

from xonsh.api.subprocess import run, check_output
from xonsh.api.os import indir
import json
import os

class ProjectManager:
    """Project management using xonsh API."""
    
    def __init__(self, project_root: str):
        """Initialize project manager.
        
        Parameters
        ----------
        project_root : str
            Root directory of the project
        """
        self.project_root = project_root
    
    def get_git_info(self) -> dict:
        """Get git repository information.
        
        Returns
        -------
        dict
            Git repository information
        """
        with indir(self.project_root):
            try:
                # Get current branch
                branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
                branch = branch.decode().strip()
                
                # Get commit hash
                commit = check_output(['git', 'rev-parse', 'HEAD'])
                commit = commit.decode().strip()
                
                # Get status
                status_result = run(['git', 'status', '--porcelain'])
                is_clean = status_result.returncode == 0 and not status_result.stdout
                
                return {
                    'branch': branch,
                    'commit': commit,
                    'is_clean': is_clean,
                    'has_git': True
                }
            except:
                return {'has_git': False}
    
    def run_tests(self) -> bool:
        """Run project tests.
        
        Returns
        -------
        bool
            True if tests pass
        """
        with indir(self.project_root):
            # Try different test runners
            test_commands = [
                ['npm', 'test'],
                ['python', '-m', 'pytest'],
                ['python', '-m', 'unittest'],
                ['make', 'test']
            ]
            
            for cmd in test_commands:
                if self._command_exists(cmd[0]):
                    result = run(cmd)
                    return result.returncode == 0
            
            return False
    
    def _command_exists(self, command: str) -> bool:
        """Check if command exists."""
        result = run(['which', command])
        return result.returncode == 0

# Usage example
project = ProjectManager('/path/to/project')
git_info = project.get_git_info()
test_result = project.run_tests()

Configuration and Environment

"""Configuration utilities using xonsh API."""

from xonsh.api.subprocess import check_output, run
from xonsh.api.os import indir
import os
import json

def detect_project_type(project_path: str) -> str:
    """Detect project type from files and configuration.
    
    Parameters
    ----------
    project_path : str
        Project directory path
        
    Returns
    -------
    str
        Project type ('python', 'node', 'go', 'rust', 'unknown')
    """
    with indir(project_path):
        # Check for specific files
        if os.path.exists('package.json'):
            return 'node'
        elif os.path.exists('pyproject.toml') or os.path.exists('setup.py'):
            return 'python'
        elif os.path.exists('go.mod'):
            return 'go'
        elif os.path.exists('Cargo.toml'):
            return 'rust'
        elif os.path.exists('Makefile'):
            return 'make'
        else:
            return 'unknown'

def get_project_dependencies(project_path: str) -> dict:
    """Get project dependencies using appropriate package manager.
    
    Parameters
    ----------
    project_path : str
        Project directory path
        
    Returns
    -------
    dict
        Dependencies information
    """
    project_type = detect_project_type(project_path)
    
    with indir(project_path):
        if project_type == 'node':
            try:
                output = check_output(['npm', 'list', '--json'])
                return json.loads(output.decode())
            except:
                return {}
        
        elif project_type == 'python':
            try:
                # Try pip list
                output = check_output(['pip', 'list', '--format=json'])
                packages = json.loads(output.decode())
                return {pkg['name']: pkg['version'] for pkg in packages}
            except:
                return {}
        
        return {}

def setup_development_environment(project_path: str) -> bool:
    """Setup development environment for project.
    
    Parameters
    ----------
    project_path : str
        Project directory path
        
    Returns
    -------
    bool
        True if setup successful
    """
    project_type = detect_project_type(project_path)
    
    with indir(project_path):
        try:
            if project_type == 'node':
                result = run(['npm', 'install'], check=True)
                return True
            
            elif project_type == 'python':
                # Create virtual environment if needed
                if not os.path.exists('venv'):
                    run(['python', '-m', 'venv', 'venv'], check=True)
                
                # Install dependencies
                if os.path.exists('requirements.txt'):
                    run(['venv/bin/pip', 'install', '-r', 'requirements.txt'], check=True)
                elif os.path.exists('pyproject.toml'):
                    run(['venv/bin/pip', 'install', '-e', '.'], check=True)
                
                return True
            
            return False
            
        except Exception as e:
            print(f"Setup failed: {e}")
            return False

Error Handling and Best Practices

Robust Error Handling

from xonsh.api.subprocess import run, check_output
from xonsh.api.os import indir
import logging

def safe_command_execution(cmd: list[str], cwd: str = None, 
                          timeout: int = 30) -> tuple[bool, str]:
    """Safely execute command with comprehensive error handling.
    
    Parameters
    ----------
    cmd : list[str]
        Command to execute
    cwd : str, optional
        Working directory
    timeout : int, default 30
        Command timeout in seconds
        
    Returns
    -------
    tuple[bool, str]
        (success, output_or_error_message)
    """
    try:
        if cwd:
            with indir(cwd):
                result = run(cmd, check=False)
        else:
            result = run(cmd, check=False)
        
        if result.returncode == 0:
            output = result.stdout if hasattr(result, 'stdout') else ""
            return True, output
        else:
            error = result.stderr if hasattr(result, 'stderr') else f"Command failed with code {result.returncode}"
            return False, error
            
    except FileNotFoundError:
        return False, f"Command '{cmd[0]}' not found"
    except PermissionError:
        return False, f"Permission denied executing '{cmd[0]}'"
    except Exception as e:
        return False, f"Unexpected error: {e}"

# Usage with error handling
success, result = safe_command_execution(['git', 'status'], cwd='/repo')
if success:
    print(f"Git status: {result}")
else:
    logging.error(f"Git command failed: {result}")

The API package provides a clean, pure Python interface to xonsh's powerful subprocess and OS utilities, making it easy to integrate xonsh capabilities into external tools and libraries without requiring a full xonsh shell environment.

Install with Tessl CLI

npx tessl i tessl/pypi-xonsh

docs

aliases.md

api-package.md

builtins-api.md

completion.md

configuration.md

directory-management.md

events.md

index.md

scripting.md

shell-interface.md

tile.json