typed-argparser is a python package to create command line programs by leveraging python type hints. It uses Python's type hints to provide a convenient way of parsing and validating command line arguments.
âś“ Type Hinting: Uses type hints to parse and validate command-line arguments.
âś“ Modular Interface: Easily define arguments and commands in a clear, organized way.
âś“ Reusable Arguments: Easily reuse arguments across multiple commands.
âś“ Nested Commands: Supports complex applications with any level of nested commands.
âś“ File Handling: Provides out-of-the-box support for handling files.
âś“ Customizable Help Messages: Fully customizable, giving you control over usage and help messages.
âś“ Built-in Validators: Comes with many built-in validators, such as time range and length validators.
âś“ Custom Types: You can define your own custom types to validate and convert command-line arguments.
âś“ Multiple Commands: Supports multiple commands in a single CLI (experimental).
You can install typed_argparser
using pip
:
pip install typed-argparser
All built-in types are supported as argument type annotations. You can also define your own custom types.
Like argparse
, you can define your own custom types to validate and convert command-line arguments to specific types.
Read more about custom types here.
type-hint | nargs | input argument | type |
---|---|---|---|
T | - | --opt <value> | T |
bool | - | --opt | bool |
Union[T1, T2, ..., TN] | - | --opt <value> | T1 | T2 | ... | TN |
Union[T, bool] | - | --opt | bool |
- | --opt <value> | T | |
List[T] | int, +, * | --opt <value>... | [T] |
- | --opt <value1> --opt <value2>... | [T] | |
Tuple[T1, T2, ..., TN] | N | --opt <value1> <value2> ... <valueN> | (T1, T2, ..., TN) |
Tuple[T, ...] | N > 2 | --opt <value1> <value2>... <valueN> | (T, ...) |
Dict[K, V] | - | --opt <key1=value1> --opt <key2=value2>... | {K: V} |
List[Dict[K, V]] | - | --opt <key1=value1> --opt <key2=value2>... | [{K: V, ...}] |
N > 2 | --opt <key1=value1> <key3=value3> --opt <key2=value2>... | [{K: V, ...}, {K: V}, ...] | |
datetime | - | --opt <value> | datetime |
date | - | --opt <value> | date |
time | - | --opt <value> | time |
Path | - | --opt <value> | Path |
Url | - | --opt <value> | Url* |
* Url is a special type that allows users to provide url as a string. It is not a built-in type but a custom type.
The possibilities are endless but remember some rules:
- Union types are resolved using the first type that matches the value. So be careful to not use
str
as the first type since everything will match a string. - nargs is only applicable for List and Tuple types.
- List without nargs allows users to use the option multiple times.
- List with nargs allows users to use multiple values (depending on nargs) for a single option.
- Dict allows users to use the option multiple times.
- Dict and List[Dict] behaves similar to each other except that the later supports nargs.
Some argument types allow you to pass arguments to them to customize their behavior.
For example, you can pass mode
to Path
type to specify the mode in which the file should be opened.
These values are passed using python's Annotated
type. A special Args
class is used to pass the arguments to the type.
For example, to pass mode
to Path
type, you can use path: Annotated[Path, Args(mode="r")] = argfield(...)
.
Following tables lists all available arguments to the types.
type | arguments | description |
---|---|---|
Path* | mode | mode in which the file should be opened |
Path* | buffering | buffering for the file |
Path* | encoding | encoding for the file |
Path* | errors | errors for the file |
Path* | newline | newline for the file |
Date | format | format for the date. defaults to "%Y-%m-%d" |
DateTime | format | format for the datetime. defaults to "%Y-%m-%dT%H:%M:%S" |
Time | format | format for the time. defaults to "%H:%M:%S" |
Url | allowed_schemes | list of allowed schemes for the url |
Url | host_required | whether the host is required or not |
Url | port_required | whether the port is required or not |
* All arguments to pathlib.Path are supported.
Additionally, args from Annotated
metadata are also automatically supplied to the validators as runtime arguments.
For example, the format argument for datetime type is also supplied to the DateTimeRangeValidator
validator so that the validator uses the correct format.
examples/example1.py
# This is a complete example and should work as is
import os
import sys
from typing import Dict, List, Optional, Tuple, Union
from typed_argparser import ArgumentClass, argfield
class Example1(ArgumentClass):
"""This example shows how to use some of the basic types in typed_argparser."""
# Positional arguments do not generate short or long options
opt1: Union[int, str] = argfield(help="opt1 is a mandatory argument which can be an integer or a string")
opt2: List[str] = argfield(help="opt2 is a mandatory argument and can be used multiple times")
# Optional arguments generate only long option by default if no short option is provided
opt3: Optional[str] = argfield(help="this is an optional argument.")
# Use Dict type to accept multiple key value pairs
opt4: Optional[Dict[str, int]] = argfield(help="accept key value pairs. can be used multiple times.")
# Use Tuple type to accept exactly n no. of arguments
opt5: Optional[Tuple[str, ...]] = argfield("-o", "--option5", nargs=4, help="accept multiple options")
cli = Example1()
"""
usage: example1 [--opt3 <value>] [--opt4 <key=value>] [-o <value1> <value2> <value3> <value4>] [--help]
<opt1> <opt2>
description:
This example shows how to use some of the basic types in typed_argparser.
positional:
<opt1> opt1 is a mandatory argument which can be an integer or a string [(int|str)]
<opt2> opt2 is a mandatory argument and can be used multiple times [str]
(multiple allowed)
options:
--opt3 <value> this is an optional argument. [str]
--opt4 <key=value> accept key value pairs. can be used multiple times. [str, int]
(multiple allowed)
-o, --option5 <value1> <value2> <value3> <value4> accept multiple options [(str,...)]
miscellaneous:
--help show this help message and exit
"""
cli.parse("--opt4 abc=10 --opt4 xyz=20 --option5 a b c d 20 abc")
"""
ParsedExample1(opt1=20, opt2=['abc'], opt3=None, opt4={'abc': 10, 'xyz': 20}, opt5=('a', 'b', 'c', 'd'))
"""
print(cli)
Check examples
directory for more examples. For more complex examples, check git_cli
example.
This section provides an overview of the API and classes used in typed_argparser.
ArgumentClass
is the main class in typed_argparser
.
It is used to define the command line interface and defines how the arguments are parsed.
To use ArgumentClass
, you need to define a subclass of it and define the arguments using the argfield
function.
All class variables are optional and can be used to customize the CLI program.
- __program__: The name of the CLI program.
- __description__:The description of the CLI program.
- __epilog__: The epilog of the CLI program.
- __usage__: The usage message of the CLI program.
- __version__: The version of the CLI program.
class CLI(ArgumentClass):
__program__ = "ls"
__description__ = "Lists the files in a directory."
__version__ = "1.0.0"
long_format: Optional[bool] = argfield("-l", "--long", help="List files in long format.")
recursive: Optional[bool] = argfield("-r", "--recursive", help="List files recursively.")
directory: List[str] = argfield("-d", nargs="+", help="Directory to list files in.")
-
ArgumentClass.parse(args: None)
Parses the command line arguments and updates the class attributes. -
ArgumentClass.execute(immediately = True, open_files = True)
Decorator to execute a function when all positional arguments of the function are provided via CLI arguments.
ArgumentConfig
is a class that holds the configuration for the ArgumentClass
. Pass this object to the ArgumentClass
constructor to customize the CLI program.
- show_default_in_help (bool): Whether to show default values in help messages. Defaults to True.
- show_none_default (bool): Whether to show default values even if they are None. Defaults to False.
- show_type_in_help (bool): Whether to show argument types in help messages. Defaults to True.
- metavar_transform (Callable[[str], str]): Function for transforming metavar strings. This is applied after all sources of metavar have been resolved.
- heading_transform (Callable[[str], str]): Function for transforming heading strings.
- add_help (bool): Whether to include help option in the parser. Defaults to True.
- groups_sort_order (List[str] | None): Order in which argument groups should be sorted in help message.
` "*" is a wildcard which signifies all groups. Defaults to ["positional", "optional", "*", "commands", "miscellaneous"].
Note: names should be an exact match to the headings. - compact_usage (bool): Whether to use compact usage message. Defaults to False.
Note: You can usecommand_metavar
andoption_metavar
to change the metavar for commands and optional arguments respectively. - default_options_group_heading (str): Default heading for options groups. Defaults to "options".
Note:heading_transform
will be applied to this parameter. - default_positional_group_heading (str): Default heading for positional groups. Defaults to "positional".
Note:heading_transform
will be applied to this parameter - default_commands_group_heading (str): Default heading for commands groups. Defaults to "commands".
Note:heading_transform
will be applied to this parameter - default_miscellaneous_group_heading (str): Default heading for miscellaneous groups. Defaults to "miscellaneous".
Note:heading_transform
will be applied to this parameter - default_description_heading (str | None): Default heading for descriptions. Defaults to "description". Set this to
None
to hide the description heading.
Note:heading_transform
will be applied to this parameter - default_usage_prefix (str): Default prefix for usage messages. Defaults to "usage: ".
Note: this value will be used as is without any transformation - command_metavar (str): Metavar string for commands. Defaults to "commmand".
Note:command_metavar
is used for bothcompact_usage
and default usage generated byArgumentClass
. Metavar transformationtransform_metavar
is only applied for default usage. Forcompact_usage
, the value is used as is. - option_metavar (str): Metavar string for options. Defaults to "option".
Note: no transformation is applied to this value. - extra_arguments (Literal["allow", "ignore", "error"]): Behavior for handling extra arguments. Defaults to "error".
When set toallow
a new propertyextra_fields
is added to the instance ofArgumentClass
. - allow_multiple_commands (bool) (experimental): Allow multiple commands. Defaults to False.
Returns an ArgumentField
object, which represents an argument in the command line interface.
- default (T | None): The default value for the argument. It must of the same type as the argument (defined by the type hint).
- nargs (int | Literal["*", "+", "?"] | None): The number of times the argument can be provided.
- const (T | None): A constant value for the argument. It must of the same type as the argument (defined by the type hint).
- dest (str | None): Specify the name of the class attribute to which the argument is assigned. Specifically used to assign multiple arguments to a single class attribute using
const
. - metavar (str | None): Alternate display name for the argument in the help message.
- aliases (Set[str] | None): A list of alternative names for a command (not applicable for arguments).
- validator (ArgumentValidator | None): An optional validator for the argument. Read more about validators here.
- counter (bool | None): Whether the argument is a counter. This is used to count the number of times an argument is provided (ex. -vvv).
- help (str | None): A help message for the argument. Set to
SUPPRESS
to hide the argument in the help message.
ArgumentGroup
is a class that represents a group of arguments in the command line interface. It is used to organize arguments into logical sections.
To define a group, you need to create a subclass of ArgumentGroup
and define the arguments using the argfield
function.
- __title__ (str): The title of the group.
- __group_description__ (str | None): An optional description of the group.
- __hide_title__ (bool): Whether to hide the title of the group in the help message.
- __exclusive__ (bool): If set to True, only one argument in the group can be provided at a time.
- __required__ (bool): If set to True, at least one argument in the mutually exclusive group must be provided.
Validators provide easy way to validate your arguments as soon as they are parsed. typed_argparser
provides certain
built-in validators but you can as easily implement your own validators (check Custom Validators).
-
Validates if the argument is of the specified length.
Parameters:- min (int | None): Minimum length of the argument.
- max (int | None): Maximum length of the argument.
-
Validates if a numeric argument is within the specified range.
Parameters:- min (int | float | None): Minimum value of the argument.
- max (int | float | None): Maximum value of the argument.
-
Validates if the argument is within the specified date, time or datetime range.
Parameters:- min (str | None): Minimum value of datetime argument.
- max (str | None): Maximum value of datetime argument.
- format (str | None): Datetime format. Defaults to "%Y-%m-%d" for date, "%H:%M:%S" for time and "%Y-%m-%dT%H:%M:%S" for datetime.
-
Validates if the argument is a valid path.
Parameters:- is_absolute (bool | None): Whether the path is absolute or not.
- is_dir (bool | None): Whether the path is a directory or not.
- is_file (bool | None): Whether the path is a file or not.
- exists (bool | None): Whether the path exists or not.
-
Validates if the argument is a valid url.
Parameters:- allowed_schemes (List[str] | None): List of allowed schemes for the url.
- host_required (bool | None): Whether the host is required or not.
- port_required (bool | None): Whether the port is required or not.
-
Validates the argument against a regex pattern.
Parameters:- pattern (str | None): Regex pattern to validate the argument.
-
This is a special validator that asks for confirmation before proceeding with the execution of the program.
If the answer does not match any of the answers provided, the program will exit with an error.
Parameters:- message (str | None): Message to display before asking for confirmation.
- abort_message (str | None): Message to display when confirmation is aborted.
- answers (List[str] | None): List of answers to accepted for confirmation.
- ignore_case (bool | None): Whether to ignore case when comparing answers. Defaults to True.
Defining commands in typed_argparser
is similar to defining arguments.
You can create a subclass of ArgumentClass
and define the arguments using the argfield
function. Then use the command class as typehint for the command argument.
class InitCommand(ArgumentClass):
quiet: Optional[bool] = argfield(
"-q", help="Only print error and warning messages; all other output will be suppressed."
)
branch: Optional[Path]= argfield("--initial-branch", "-b", help="Use the specified name for the initial branch in the newly created repository.")
class Git(ArgumentClass):
init: InitCommand = argfield(help="Initialize a new Git repository.")
To be updated soon.
To define a custom validator, you need to create a subclass of ArgumentValidator
and define 2 methods: __init__
and validator
.
__init__
accepts the validator arguments as keyword arguments and is used to initialize the validator.
validator
accepts the value to be validated as a parameter and is used to validate the value. Any runtime arguments are passed to the validator as keyword arguments.
Simple example of a custom validator that validates if a numnber is within a range:
class MyValidator(ArgumentValidator):
def __init__(self, min: Optional[int] = None, max: Optional[int] = None) -> None:
if (min and max and min >= max) or (min is None and max is None):
raise ValidatorInitError("invalid range provided", validator=self)
self.min = min
self.max = max
def validator(self, value: str) -> None:
if self.min and self.max and (len(value) < self.min or len(value) > self.max):
raise ValidationError(f"string length should be between {self.min} and {self.max}", validator=self)
if self.min and len(value) < self.min:
raise ValidationError(f"string length should be greater than {self.min}", validator=self)
if self.max and len(value) > self.max:
raise ValidationError(f"string length should be less than {self.max}", validator=self)
If you are interested in contributing to typed_argparser, please take a look at the contributing guidelines.