Python-powered shell providing superset of Python with shell primitives for cross-platform command execution and automation.
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.
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'])
"""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#!/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 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 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 Falsefrom 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