A package to simplify the creation of Python Command-Line tools
Project description
Command Creator
Command Creator is a Python package that simplifies the creation of command-line interfaces (CLIs) using Python's dataclasses
.
It allows you to define commands as dataclass objects, making it easy to create, manage, and execute commands with various options and arguments.
This package is particularly useful for developers who want to quickly set up CLIs without having to write extensive boilerplate code.
Table of Contents
- Table of Contents
- Simple Usage
- CLI Argument Features
- Sub-commands
- Using with Sphinx-Autoprogram
- BASH and ZSH Auto-complete
Simple Usage
The command_creator
package can be used to automatically create CLIs from dataclass objects.
This is done using the @dataclass
decorator, command_creator.arg
method, and the command_creator.Command
class.
from dataclasses import dataclass
from command_creator import arg, Command
# A command is a class which extends command_creator.Command and is a dataclass
@dataclass
class SimpleCommand(Command):
"""This doc-string is used as the command description in the help message"""
positional: str = arg(
help="This is a positional argument, since it has no default"
)
extra_positional: str = arg(
default="Not-Given",
positional=True,
help="This is an extra positional argument, since it has 'positional=True'"
)
option: bool = arg(
default=False,
help="This is the --option argument which when given sets self.option to true"
)
output_file: str | None = arg(
default=None,
help="This is the '--output-file OUTPUT_FILE' argument"
)
args: list[str] | None = arg(
default=None,
help="This is the '--args ARGS [ARGS ...]' argument"
)
# The __post_init__ method is called after creation of the object, but before running the command
# It is optional
def __post_init__(self) -> None:
pass
# The __call__ method is required. This is the entry point for the command
def __call__(self) -> int:
print("Doing something")
return 0
# The execute class method can be used to parse command-line arguments and run the command
if __name__ == "__main__":
SimpleCommand.execute()
CLI Argument Features
Each dataclass field represents a command-line argument.
In order to add functionality, these must use command_creator.arg
to instantiate rather than dataclasses.field
.
This section outlines how this method can be used to create a wide-range of arguments.
Positional Arguments and Options
In unix-style CLI there are two main ways data can be passed to the underlying command: as a positional argument or as an option.
Positional arguments are interpreted based soley on their position.
However, options use -
characters and a name to denote their intended use.
For example --debug
is an option which might tell the underlying command to run in debug mode regardless of where it provided.
Command Creator uses 3-indicators to determine whether an arugment should be interpreted as a Positional Arugment or an Option:
-
positional
- Arguments which have
positional=True
are always treats as Positional Arguments - See positional_ for more details
- Arguments which have
-
default
anddefault_factory
- Arguments with a default are treated as options unless they are explicitly positional.
- See
default and default_factory
_ for more details
-
count
- Arguments which have
count=True
are treated as Options even if they don't have a default, because there is no command-line concept of counting positional arguments. count=True
is mutually exclusive withpositional
- See count_ for more details
- Arguments which have
help
The help
argument takes a string which is used for the help message of the command
abrv
The abrv
argument takes a string which is used as the -[abrv]
abreviated option.
choices
The choices
argument takes a list or enum type which sets the valid inputs to the option/positional argument.
If the provided argument is a subclass of the paython standard Enum
then the options are the uppercase names of the enumerated values.
metavar
The metavar
argument takes a string which is used as the METAVAR
in the help string.
optional
The optional
argument takes a boolean and determines the following based on the argument:
-
If the argument is positional
- Then the positional argument can be excluded in the command line
- If the argument is excluded and a default is given then the field gets set to the default
- If the argument is excluded and no default is given then the field gets set to
None
-
If the argument is an option
- Then the optional option can be provided without an argument after it
- If the option is excluded from the command-line then the field gets set to the default
- If the option is provided w/o an argument then the field gets set to
None
- If the option is provided w/ an argument then the field gets set to the provided argument
positional
The positional
argument takes a boolean.
When true it forces the argument to be positional rather than an option.
default and default_factory
Provides defaults to the underlying argument if it is not specified on the command-line.
default_factory
is a callable that can be used to create new objects at run-time.
See the Python dataclasses
module documentation for more details.
count
A boolean which indicates that the argument is a counting option.
This means that the argument can be provided multiple times and the value of the field will be the number of times the argument was provided.
For example, if the argument is --verbose
and it is provided 3 times, then the field will be set to 3
.
This is useful for options that can be repeated to increase their effect, such as --verbose
or --debug
.
It is mutually exclusive with positional
, meaning that an argument cannot be both positional and a counting option.
completer
The completer
argument takes an object which can be used by argcomplete to provide auto-completion for the argument.
This is useful for options that can take a limited set of values, such as --color
which might take values like red
, green
, or blue
.
The completer should be a callable that takes no arguments and returns a list of strings.
For example, if you have a list of colors, you could use the following:
def color_completer():
return ["red", "green", "blue"]
Sub-commands
@dataclass
class ReusableSubCommand(Command):
opt1: str = arg()
def __call__(self) -> int:
print("A sub-command which can be used across a variety of contexts")
return 0
@dataclass
class ParentCommand(Command):
@dataclass
class SpecificSubCommand(Command):
opt2: str = arg()
def __call__(self) -> int:
print("A sub-command for use only in this parent command")
return 0
sub_commands = {
"specific": SpecificSubCommand,
"reusable": ReusableSubCommand,
}
def __call__(self) -> int:
if self.sub_command is not None:
self.sub_command()
Using with Sphinx-Autoprogram
.. autoprogram:: pkg_name.module:CommandClass.create_parser(True)
BASH and ZSH Auto-complete
Bash and ZSH Auto-complete can be enabled by adding the following line to the top of your script.
This will allow the command to be auto-completed in the shell.
Additionally, the argcomplete
package must be installed.
# PYTHON_ARGCOMPLETE_OK
@dataclass
class MyCommand(Command):
# Your command definition here
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file command_creator-2.3.1.tar.gz
.
File metadata
- Download URL: command_creator-2.3.1.tar.gz
- Upload date:
- Size: 39.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
581d52931c1658cc9728f9c04e598bb21c0830b7338b54e7696390d8adfabfd2
|
|
MD5 |
0116b20b5baaf594cb25de608771c86e
|
|
BLAKE2b-256 |
1839e404e9f5d1f2f9333ae080fc40509ea6bc0853bbe8ab90d8638002062203
|
Provenance
The following attestation bundles were made for command_creator-2.3.1.tar.gz
:
Publisher:
publish.yml
on allRisc/command_creator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
command_creator-2.3.1.tar.gz
-
Subject digest:
581d52931c1658cc9728f9c04e598bb21c0830b7338b54e7696390d8adfabfd2
- Sigstore transparency entry: 346635523
- Sigstore integration time:
-
Permalink:
allRisc/command_creator@504c0a8d1433285f22dbc4a1a19bc567b1596f0f
-
Branch / Tag:
refs/tags/2.3.1
- Owner: https://github.com/allRisc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@504c0a8d1433285f22dbc4a1a19bc567b1596f0f
-
Trigger Event:
push
-
Statement type:
File details
Details for the file command_creator-2.3.1-py3-none-any.whl
.
File metadata
- Download URL: command_creator-2.3.1-py3-none-any.whl
- Upload date:
- Size: 29.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
3fedfed198665b8d0a0351e383b37920f64086190d646d764f7624c1fd7def10
|
|
MD5 |
bdb6575fe505113f6d096c517f4c70e2
|
|
BLAKE2b-256 |
7faf412283cf67e5556d06169626c8e8a47ee2a37c6f1d79bebca1210452a468
|
Provenance
The following attestation bundles were made for command_creator-2.3.1-py3-none-any.whl
:
Publisher:
publish.yml
on allRisc/command_creator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
command_creator-2.3.1-py3-none-any.whl
-
Subject digest:
3fedfed198665b8d0a0351e383b37920f64086190d646d764f7624c1fd7def10
- Sigstore transparency entry: 346635525
- Sigstore integration time:
-
Permalink:
allRisc/command_creator@504c0a8d1433285f22dbc4a1a19bc567b1596f0f
-
Branch / Tag:
refs/tags/2.3.1
- Owner: https://github.com/allRisc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@504c0a8d1433285f22dbc4a1a19bc567b1596f0f
-
Trigger Event:
push
-
Statement type: