Top Related Projects
Quick Overview
Argh is a Python library that simplifies command-line argument parsing. It provides a user-friendly interface for creating command-line interfaces (CLIs) with minimal boilerplate code, making it easier for developers to build robust CLI applications.
Pros
- Simple and intuitive API, reducing the learning curve for developers
- Automatic generation of help messages and usage information
- Supports both positional and named arguments with minimal configuration
- Seamlessly integrates with existing Python functions and methods
Cons
- Limited advanced features compared to more comprehensive libraries like argparse
- May not be suitable for extremely complex CLI applications with intricate argument structures
- Less actively maintained compared to some alternative libraries
- Documentation could be more extensive and up-to-date
Code Examples
- Basic usage:
from argh import arg, dispatch_command
@arg('name', help='Your name')
@arg('--greeting', help='Greeting to use', default='Hello')
def greet(name, greeting='Hello'):
return f"{greeting}, {name}!"
if __name__ == '__main__':
dispatch_command(greet)
- Multiple commands:
from argh import arg, dispatch_commands
def add(a: int, b: int):
return a + b
@arg('--uppercase', help='Convert to uppercase')
def echo(text: str, uppercase=False):
return text.upper() if uppercase else text
if __name__ == '__main__':
dispatch_commands([add, echo])
- Nested commands:
from argh import arg, dispatch_command
def main():
pass
@arg('name', help='Repository name')
def create(name):
return f"Created repository: {name}"
main.create = create
if __name__ == '__main__':
dispatch_command(main)
Getting Started
To get started with Argh, first install it using pip:
pip install argh
Then, create a Python file (e.g., cli.py
) with your command-line interface:
from argh import arg, dispatch_command
@arg('name', help='Your name')
def greet(name):
return f"Hello, {name}!"
if __name__ == '__main__':
dispatch_command(greet)
Run your CLI application:
python cli.py John
This will output: "Hello, John!"
Competitor Comparisons
Create *beautiful* command-line interfaces with Python
Pros of docopt
- Declarative approach using POSIX-style usage patterns
- Automatically generates help messages from the usage patterns
- Supports a wide range of programming languages beyond Python
Cons of docopt
- Less flexible for complex command-line interfaces
- May require more verbose usage patterns for intricate options
- Limited built-in type validation and conversion
Code Comparison
docopt:
"""Naval Fate.
Usage:
naval_fate ship new <name>...
naval_fate ship <name> move <x> <y> [--speed=<kn>]
naval_fate ship shoot <x> <y>
naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
naval_fate -h | --help
naval_fate --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
"""
argh:
@argh.arg('--speed', default=10)
@argh.arg('name', nargs='+')
def ship_new(name):
pass
@argh.arg('--speed', default=10)
def ship_move(name, x, y, speed=10):
pass
parser = argh.ArghParser()
parser.add_commands([ship_new, ship_move])
Typer, build great CLIs. Easy to code. Based on Python type hints.
Pros of Typer
- Modern Python features: Utilizes type hints and async support
- Rich CLI features: Offers advanced features like subcommands and option groups
- Extensive documentation: Provides detailed guides and examples
Cons of Typer
- Steeper learning curve: More complex API compared to Argh's simplicity
- Heavier dependencies: Relies on FastAPI and its ecosystem
Code Comparison
Typer:
import typer
app = typer.Typer()
@app.command()
def hello(name: str):
typer.echo(f"Hello {name}")
if __name__ == "__main__":
app()
Argh:
from argh import arg, dispatch_command
@arg('name')
def hello(name):
print(f"Hello {name}")
if __name__ == '__main__':
dispatch_command(hello)
Summary
Typer offers more advanced features and modern Python support, making it suitable for complex CLI applications. Argh, on the other hand, provides a simpler and more lightweight approach, ideal for quick and straightforward command-line tools. The choice between the two depends on the project's requirements and the developer's preference for simplicity versus feature-richness.
Python composable command line interface toolkit
Pros of Click
- More comprehensive and feature-rich, offering advanced functionality like subcommands and option groups
- Extensive documentation and a larger community, providing better support and resources
- Built-in support for generating command-line help messages and auto-completion
Cons of Click
- Steeper learning curve due to its more complex API and extensive features
- Slightly more verbose syntax for simple use cases
- Larger dependency footprint compared to Argh's lightweight approach
Code Comparison
Click:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
for _ in range(count):
click.echo(f"Hello, {name}!")
Argh:
from argh import arg, dispatch_command
@arg('--name', help='The person to greet')
@arg('-c', '--count', default=1, help='Number of greetings')
def hello(name, count=1):
for _ in range(count):
print(f"Hello, {name}!")
dispatch_command(hello)
Both libraries offer similar functionality, but Click provides a more structured approach with decorators, while Argh aims for simplicity and minimal boilerplate code.
A non-validating SQL parser module for Python
Pros of sqlparse
- Specialized for SQL parsing and formatting
- More comprehensive SQL support with features like statement splitting
- Actively maintained with regular updates
Cons of sqlparse
- Limited to SQL-specific functionality
- Steeper learning curve for non-SQL-related tasks
- Larger codebase and potentially slower for simple parsing tasks
Code Comparison
sqlparse example:
import sqlparse
sql = "SELECT * FROM table WHERE id = 1"
formatted = sqlparse.format(sql, reindent=True, keyword_case='upper')
print(formatted)
argh example:
from argh import arg, dispatch_command
@arg('name', help='Your name')
def greet(name):
return f"Hello, {name}!"
dispatch_command(greet)
Summary
sqlparse is a specialized library for SQL parsing and formatting, offering comprehensive SQL support. It's ideal for projects heavily focused on SQL manipulation. argh, on the other hand, is a general-purpose command-line argument parsing library, providing a simpler interface for creating command-line tools. While sqlparse excels in SQL-related tasks, argh offers broader applicability for various command-line applications.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Argh
Argh is an opinionated Derive-based argument parser optimized for code size
Derive-based argument parsing optimized for code size and conformance to the Fuchsia commandline tools specification
The public API of this library consists primarily of the FromArgs
derive and the from_env
function, which can be used to produce
a top-level FromArgs
type from the current program's commandline
arguments.
Basic Example
use argh::FromArgs;
#[derive(FromArgs)]
/// Reach new heights.
struct GoUp {
/// whether or not to jump
#[argh(switch, short = 'j')]
jump: bool,
/// how high to go
#[argh(option)]
height: usize,
/// an optional nickname for the pilot
#[argh(option)]
pilot_nickname: Option<String>,
}
fn main() {
let up: GoUp = argh::from_env();
}
./some_bin --help
will then output the following:
Usage: cmdname [-j] --height <height> [--pilot-nickname <pilot-nickname>]
Reach new heights.
Options:
-j, --jump whether or not to jump
--height how high to go
--pilot-nickname an optional nickname for the pilot
--help, help display usage information
The resulting program can then be used in any of these ways:
./some_bin --height 5
./some_bin -j --height 5
./some_bin --jump --height 5 --pilot-nickname Wes
Switches, like jump
, are optional and will be set to true if provided.
Options, like height
and pilot_nickname
, can be either required,
optional, or repeating, depending on whether they are contained in an
Option
or a Vec
. Default values can be provided using the
#[argh(default = "<your_code_here>")]
attribute, and in this case an
option is treated as optional.
use argh::FromArgs;
fn default_height() -> usize {
5
}
#[derive(FromArgs)]
/// Reach new heights.
struct GoUp {
/// an optional nickname for the pilot
#[argh(option)]
pilot_nickname: Option<String>,
/// an optional height
#[argh(option, default = "default_height()")]
height: usize,
/// an optional direction which is "up" by default
#[argh(option, default = "String::from(\"only up\")")]
direction: String,
}
fn main() {
let up: GoUp = argh::from_env();
}
Custom option types can be deserialized so long as they implement the
FromArgValue
trait (automatically implemented for all FromStr
types).
If more customized parsing is required, you can supply a custom
fn(&str) -> Result<T, String>
using the from_str_fn
attribute:
use argh::FromArgs;
#[derive(FromArgs)]
/// Goofy thing.
struct FiveStruct {
/// always five
#[argh(option, from_str_fn(always_five))]
five: usize,
}
fn always_five(_value: &str) -> Result<usize, String> {
Ok(5)
}
Positional arguments can be declared using #[argh(positional)]
.
These arguments will be parsed in order of their declaration in
the structure:
use argh::FromArgs;
#[derive(FromArgs, PartialEq, Debug)]
/// A command with positional arguments.
struct WithPositional {
#[argh(positional)]
first: String,
}
The last positional argument may include a default, or be wrapped in
Option
or Vec
to indicate an optional or repeating positional argument.
Subcommands are also supported. To use a subcommand, declare a separate
FromArgs
type for each subcommand as well as an enum that cases
over each command:
use argh::FromArgs;
#[derive(FromArgs, PartialEq, Debug)]
/// Top-level command.
struct TopLevel {
#[argh(subcommand)]
nested: MySubCommandEnum,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum MySubCommandEnum {
One(SubCommandOne),
Two(SubCommandTwo),
}
#[derive(FromArgs, PartialEq, Debug)]
/// First subcommand.
#[argh(subcommand, name = "one")]
struct SubCommandOne {
#[argh(option)]
/// how many x
x: usize,
}
#[derive(FromArgs, PartialEq, Debug)]
/// Second subcommand.
#[argh(subcommand, name = "two")]
struct SubCommandTwo {
#[argh(switch)]
/// whether to fooey
fooey: bool,
}
NOTE: This is not an officially supported Google product.
How to debug the expanded derive macro for argh
The argh::FromArgs
derive macro can be debugged with the cargo-expand crate.
Expand the derive macro in examples/simple_example.rs
See argh/examples/simple_example.rs for the example struct we wish to expand.
First, install cargo-expand
by running cargo install cargo-expand
. Note this requires the nightly build of Rust.
Once installed, run cargo expand
with in the argh
package and you can see the expanded code.
Top Related Projects
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot