
ArgøNaut
A powerful and flexible argument parsing library for Python.
Features
Intuitive API
ArgøNaut provides an intuitive API similar to argparse, making it easy for developers familiar with Python's standard library to adopt.
Subcommands
Create complex CLI applications with nested subcommands, allowing for a more organized and scalable command structure.
Custom Validators
Implement custom validation logic for your arguments to ensure data integrity and improve user experience.
Plugin System
Extend ArgøNaut's functionality with a powerful and flexible plugin system, allowing for modular development.
Type Safety
Benefit from automatic type conversion and validation for your arguments, reducing the risk of runtime errors.
Shell Completion
Generate shell completion scripts for bash, zsh, and fish to enhance the command-line experience.
Advanced Argument Handling
Support for positional arguments, optional arguments, flags, and complex argument types. Implement custom actions and validators for fine-grained control over argument behavior.
Input Sanitization
Built-in input sanitization to protect against malicious input, including protection against shell injection and directory traversal attacks.
Asynchronous Support
Integration with asyncio for asynchronous argument parsing and plugin execution, enabling efficient handling of I/O-bound operations.
Customizable Output
Colored output and progress bars for better readability and user feedback.
Cross-Platform Compatibility
Seamless operation across Windows, macOS, and Linux environments.
Configuration File Support
Load arguments from YAML or JSON configuration files for flexible setup.
Automatic Man Page Generation
Generate man pages automatically for your CLI tool.
Asynchronous Support
Use ArgøNaut with asyncio for asynchronous applications.
Installation
Install via pip
pip install argonautCli
Quick Start
Basic Usage
from argonaut import Argonaut
parser = Argonaut(description="My awesome CLI tool")
parser.add("--name", help="Your name")
parser.add("--age", type=int, help="Your age")
args = parser.parse()
print(f"Hello, {args['name']}! You are {args['age']} years old.")
API Reference
The main class for creating a command-line interface.
Constructor:
__init__(description: str, epilog: str = "", custom_help_formatter: Optional[Callable] = None)
: Initialize the Argonaut parser.
Key Methods:
add(*names, **kwargs) -> Argument
: Add a new argument to the parser.add_subcommand(name: str, **kwargs) -> SubCommand
: Add a new subcommand to the parser.parse(args: Optional[List[str]] = None) -> Dict[str, Any]
: Parse command-line arguments.parse_async(args: Optional[List[str]] = None, ignore_unknown: bool = False) -> Dict[str, Any]
: Asynchronously parse command-line arguments.load_plugin(module_path: str)
: Load a plugin from the specified module path.execute_plugin(name: str, args: Dict[str, Any])
: Execute a loaded plugin with the given arguments.execute_plugin_async(name: str, args: Dict[str, Any]) -> Any
: Asynchronously execute a loaded plugin.
Represents a single argument in the command-line interface.
Constructor:
__init__(*names: str, **kwargs)
: Initialize an Argument object.
Methods:
validate(value: Any) -> Any
: Validate the argument value.get_default() -> Any
: Get the default value for the argument.handle_action(value: Any) -> Any
: Handle the action for the argument.with_default(default_value: Any) -> Argument
: Create a new Argument with a different default value.with_type(new_type: Callable) -> Argument
: Create a new Argument with a different type.with_validator(validator: Callable[[Any], bool]) -> Argument
: Create a new Argument with an additional validator.set_custom_action(func: Callable[[Any], Any]) -> Argument
: Set a custom action for the argument.
Represents a subcommand in the command-line interface.
Constructor:
__init__(name: str, description: str = "", **kwargs)
: Initialize a SubCommand object.
Methods:
add(*names, **kwargs) -> Argument
: Add a new argument to the subcommand.add_group(title: str, description: str = "") -> ArgumentGroup
: Add a new argument group to the subcommand.add_exclusive_group() -> MutuallyExclusiveGroup
: Add a mutually exclusive group to the subcommand.add_subcommand(name: str, **kwargs) -> SubCommand
: Add a nested subcommand.parse_arguments(args: List[str]) -> Dict[str, Any]
: Parse arguments for the subcommand.generate_help() -> str
: Generate a help message for the subcommand.
Advanced Usage
Custom Validators
from argonautCli import Argonaut, custom_validator
@custom_validator
def validate_positive(value):
if value <= 0:
raise ValueError("Value must be positive")
return value
parser = Argonaut()
parser.add("--count", type=int, validator=validate_positive)
Asynchronous Plugin Execution
import asyncio
from argonautCli import Argonaut
async def main():
parser = Argonaut()
parser.load_plugin("my_async_plugin")
args = await parser.parse_async()
result = await parser.execute_plugin_async("my_async_plugin", args)
print(result)
asyncio.run(main())
Subcommands
parser = Argonaut()
subcommand = parser.add_subcommand("run")
subcommand.add("--input", help="Input file")
Argument Groups
parser = Argonaut()
group = parser.add_group("Input Options")
group.add("--input", help="Input file")
group.add("--format", choices=["json", "yaml"], help="Input format")
Mutually Exclusive Arguments
parser = Argonaut()
group = parser.add_mutually_exclusive_group()
group.add("--verbose", action="store_true", help="Increase verbosity")
group.add("--quiet", action="store_true", help="Decrease verbosity")
Environment Variables
from argonautCli import Argonaut, env_var
parser = Argonaut()
parser.add("--api-key", env_var="API_KEY", help="API key (can be set via API_KEY env var)")
Custom Actions
from argonautCli import Argonaut, custom_action
def uppercase_action(value):
return value.upper()
parser = Argonaut()
parser.add("--text", action=uppercase_action, help="Convert text to uppercase")
Configuration Files
parser = Argonaut()
parser.load_config("config.yaml")
# or
parser.load_config("config.json")
Generating Man Pages
parser = Argonaut()
parser.write_man_page("my_tool.1")
Asynchronous Support
from argonaut import Argonaut
parser = Argonaut()
parser.add("--async-option", help="An async option")
async def main():
args = await parser.parse_async()
result = await parser.execute_plugin_async("my_plugin", args)
print(result)
import asyncio
asyncio.run(main())
Environment Variables
from argonaut import Argonaut
parser = Argonaut()
parser.add("--api-key", env_var="API_KEY", help="API key (can be set via API_KEY env var)")
args = parser.parse()
print(f"API Key: {args['api_key']}")
Examples
File Processing CLI
from argonaut import Argonaut
parser = Argonaut(description="File processing tool")
parser.add("input_file", help="Path to the input file")
parser.add("--output", help="Path to the output file")
parser.add("--verbose", action="store_true", help="Enable verbose output")
args = parser.parse()
# Your file processing logic here
print(f"Processing {args['input_file']}...")
if args['verbose']:
print("Verbose mode enabled")
if args['output']:
print(f"Output will be saved to {args['output']}")
Plugin System
ArgøNaut features a powerful plugin system that allows you to extend the functionality of your CLI applications.
Creating a Plugin
from argonaut import Plugin, PluginMetadata
class MyPlugin(Plugin):
@property
def metadata(self) -> PluginMetadata:
return PluginMetadata(
name="my_plugin",
version="1.0.0",
description="A sample plugin for ArgøNaut",
author="Your Name",
website="https://example.com",
tags=["sample", "demo"]
)
def initialize(self, context):
self.context = context
def execute(self, args):
return f"Hello from MyPlugin! Args: {args}"
async def execute_async(self, args):
# Asynchronous execution method
return await some_async_operation(args)
def on_load(self):
print("Plugin loaded")
def on_unload(self):
print("Plugin unloaded")
def on_command_execution(self, command):
print(f"Command '{command}' is being executed")
Plugin Properties
Property | Required | Description |
---|---|---|
metadata | Required | Provides metadata about the plugin |
initialize | Required | Called when the plugin is initialized |
execute | Required | Main execution method for the plugin |
execute_async | Optional | Asynchronous execution method |
on_load | Optional | Called when the plugin is loaded |
on_unload | Optional | Called when the plugin is unloaded |
on_command_execution | Optional | Called before a command is executed |
Development
Setting Up the Development Environment
- Clone the repository:
git clone https://github.com/sc4rfurry/argonaut.git cd argonaut
- Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows, use `venv\Scripts\activate`
- Install development dependencies:
pip install -r requirements.txt
Contributing
We welcome contributions to ArgøNaut! Please follow these steps to contribute:
- Fork the repository on GitHub.
- Create a new branch for your feature or bug fix.
- Write tests for your changes.
- Implement your changes.
- Run the tests to ensure everything is working.
- Submit a pull request with a clear description of your changes.
FAQ
Changelog
Version 1.2.0 (2024-07-30)
- Added asynchronous support for argument parsing and plugin execution
- Improved error handling and reporting
- Enhanced cross-platform compatibility
- Implemented advanced progress visualization and Color Output (Work in progress)
- Added support for dynamic argument handling
- Improved plugin system with better lifecycle management