A wrapper around the standard argparse module that allows you to describe argument parsers declaratively.
Project description
A wrapper around the standard argparse module that allows you to describe argument parsers declaratively.
By default, the argparse module suggests creating parsers imperative, which is not convenient from the point of view of type checking and access to attributes, of course, IDE autocompletion and type hints not applicable in this case.
This module allows you to declare command-line parsers with classes.
Simple example:
import logging
import argclass
class CopyParser(argclass.Parser):
recursive: bool
preserve_attributes: bool
parser = CopyParser()
parser.parse_args(["--recursive", "--preserve-attributes"])
assert parser.recursive
assert parser.preserve_attributes
As you can see this example shown a basic module usage, when you want specify argument default and other options you have to use argclass.Argument.
Following example use argclass.Argument and argument groups:
import logging
import argclass
class AddressPortGroup(argclass.Group):
address: str = argclass.Argument(default="127.0.0.1")
port: int
class Parser(argclass.Parser):
log_level: int = argclass.LogLevel
http = AddressPortGroup(title="HTTP options", defaults=dict(port=8080))
rpc = AddressPortGroup(title="RPC options", defaults=dict(port=9090))
parser = Parser(
config_files=[".example.ini", "~/.example.ini", "/etc/example.ini"],
auto_env_var_prefix="EXAMPLE_"
)
parser.parse_args([])
logging.basicConfig(level=parser.log_level)
logging.info('Listening http://%s:%d', parser.http.address, parser.http.port)
logging.info(f'Listening rpc://%s:%d', parser.rpc.address, parser.rpc.port)
assert parser.http.address == '127.0.0.1'
assert parser.rpc.address == '127.0.0.1'
assert parser.http.port == 8080
assert parser.rpc.port == 9090
Run this script:
$ python example.py
INFO:root:Listening http://127.0.0.1:8080
INFO:root:Listening rpc://127.0.0.1:9090
Example of --help output:
$ python example.py --help
usage: example.py [-h] [--log-level {debug,info,warning,error,critical}]
[--http-address HTTP_ADDRESS] [--http-port HTTP_PORT]
[--rpc-address RPC_ADDRESS] [--rpc-port RPC_PORT]
optional arguments:
-h, --help show this help message and exit
--log-level {debug,info,warning,error,critical}
(default: info) [ENV: EXAMPLE_LOG_LEVEL]
HTTP options:
--http-address HTTP_ADDRESS
(default: 127.0.0.1) [ENV: EXAMPLE_HTTP_ADDRESS]
--http-port HTTP_PORT
(default: 8080) [ENV: EXAMPLE_HTTP_PORT]
RPC options:
--rpc-address RPC_ADDRESS
(default: 127.0.0.1) [ENV: EXAMPLE_RPC_ADDRESS]
--rpc-port RPC_PORT (default: 9090) [ENV: EXAMPLE_RPC_PORT]
Default values will based on following configuration files ['example.ini',
'~/.example.ini', '/etc/example.ini']. Now 1 files has been applied
['example.ini']. The configuration files is INI-formatted files where
configuration groups is INI sections.
See more https://pypi-hypernode.com/project/argclass/#configs
Configs
The parser objects might be get default values from environment variables or one of passed configuration files.
class AddressPortGroup(argclass.Group):
address: str = argclass.Argument(default="127.0.0.1")
port: int
class Parser(argclass.Parser):
spam: str
quantity: int
log_level: int = argclass.LogLevel
http = AddressPortGroup(title="HTTP options")
rpc = AddressPortGroup(title="RPC options")
# Trying to parse all passed configuration files
# and break after first success.
parser = Parser(
config_files=[".example.ini", "~/.example.ini", "/etc/example.ini"],
)
parser.parse_args()
In this case each passed and existent configuration file will be opened.
The root level arguments might described in the [DEFAULT] section.
Other arguments might be described in group specific sections.
So the full example of config file for above example is:
[DEFAULT]
log_level=info
spam=egg
quantity=100
[http]
address=127.0.0.1
port=8080
[rpc]
address=127.0.0.1
port=9090
Subparsers
Complex example with subparsers:
import logging
from functools import singledispatch
from pathlib import Path
from typing import Optional, Any
import argclass
class AddressPortGroup(argclass.Group):
address: str = argclass.Argument(default="127.0.0.1")
port: int
class CommitCommand(argclass.Parser):
comment: str = argclass.Argument()
class PushCommand(argclass.Parser):
comment: str = argclass.Argument()
class Parser(argclass.Parser):
log_level: int = argclass.LogLevel
endpoint = AddressPortGroup(
title="Endpoint options",
defaults=dict(port=8080)
)
commit: Optional[CommitCommand] = CommitCommand()
push: Optional[PushCommand] = PushCommand()
@singledispatch
def handle_subparser(subparser: Any) -> None:
raise NotImplementedError(
f"Unexpected subparser type {subparser.__class__!r}"
)
@handle_subparser.register(type(None))
def handle_commit(_: None) -> None:
pass
@handle_subparser.register(CommitCommand)
def handle_commit(subparser: CommitCommand) -> None:
pass
@handle_subparser.register(PushCommand)
def handle_commit(subparser: PushCommand) -> None:
pass
parser = Parser(
config_files=["example.ini", "~/.example.ini", "/etc/example.ini"],
auto_env_var_prefix="EXAMPLE_"
)
parser.parse_args()
handle_subparser(parser.current_subparser)
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
File details
Details for the file argclass-0.4.1.tar.gz
.
File metadata
- Download URL: argclass-0.4.1.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.0 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed14d8efe32509e4f5a6dafe88a3b7868b9e66db3ae2bcbfe130ff78b1f5e7cd |
|
MD5 | f63f579e7f195e48f9c732cb7deb690a |
|
BLAKE2b-256 | 23907193653fa1a61b121399e9912c67f37fe041a1f540a84c5e9f436f25f8b0 |