Simple config and argument system
Project description
hackerargs
hackerargs minimizes new lines of code to add a new argument, command line option,
or config anywhere in your codebase.
Its design enables you to start hacking, prototyping, writing code,
and focus on experiments while spending zero time thinking about argument handling.
Once initialized by parsing command line arguments in --{key} {val}
format,
and/or loading from YAML, hackerargs acts as a global, write-once-only dict,
accessible anywhere in your codebase with from hackerargs import args
.
Hackerargs automatically infers python object types, saves to YAML enabling
exact reproducibility, optionally integrates with argparse, and works smoothly with wandb sweeps.
Hackerargs' philosophy is "build first, document later": it does not force you to make arguments discoverable and well-documented. To do so, we recommend using argparse to build help messages and descriptions of key arguments, and sharing YAML config files.
Installation
pip install hackerargs
Usage
# in your driver script
from hackerargs import args
if __name__ == '__main__':
args.parse_args() # parses command-line args in --{key} val format
main()
args.save_to_yaml(yaml_file)
# in any python script/file, anywhere in your codebase
from hackerargs import args
class Model:
def __init__(self):
self.parameter = args.setdefault(key, default_value)
hackerargs acts as a global write-once-only dict after initialization.
Hackerargs is built around value = args.setdefault(key, default_value)
,
which returns the value of the specified key if set already.
If the key does not exist, its value is first set to default_value.
setdefault is a standard method on python dicts, albeit relatively unknown.
We recommend mainly using setdefault:
- Write code thinking forward, not backward: Once you call setdefault, you're guaranteed to have a reasonable value, set from the command line, yaml config, or the default value. Run forth and use it.
- Exact reproducibility: A write-once-only dict ensures that running the script and saving populated args to yaml, enables reloading that yaml config to rerun the script with the exact same argument settings.
Easy CLI options
from hackerargs import args
if __name__ == '__main__':
args.parse_args() # parses command line args in --{key} val format
lr = args.setdefault('lr', 1.0e-3)
If we run this script as python train.py --lr 1.0e-1
, then we get:
args = {'lr': 0.1}
lr
was first specified by the user on the command line, and parsed into args, so setdefault defers to that. This lets you easily set up wandb sweeps.
Access
>>> args.setdefault('lr', 1e-4)
0.1
>>> args.get('lr')
0.1
>>> args['lr']
0.1
>>> args.lr
0.1
When a key might not be set, we recommend using setdefault for access. When you're sure the key is set already, hackerargs supports .get, bracket access, and dot access.
Type inference & loading from YAML
string: text
none: [~, null]
bool: [true, false, on, off]
int: 42 # comment on int
float: 3.14159
list: [LITE, RES_ACID, SUS_DEXT]
Command line:
python example.py --config config_yaml_file
: Whenargs.parse_args()
is called, initialize args with yaml_file.--config
is a protected command-line option.
In python:
args.parse_args(config_yaml_file)
: Initialize using yaml file, then parse CLI options in--{key} {val}
format.
Equivalent to:
python example.py --string text --none [~,null] --bool [true,false,on,off,yes,no] --int 42 --float 3.14159 --list [LITE,RES_ACID,SUS_DEXT]
and callingargs.parse_args()
.
args = {
'string': 'text',
'none': [None, None],
'bool': [True, False, 'on', 'off', 'yes', 'no'],
'int': 42,
'float': 3.14159,
'list': ['LITE', 'RES_ACID', 'SUS_DEXT']
}
Hackerargs infers types using PyYAML's loader, which follows YAML v1.1. The exception is we do not infer yes/no/on/off as booleans, which was removed in YAML v1.2.
Compatibility with argparse
Build your own ArgumentParser, and pass it to hackerarg:
import argparse
from hackerargs import args
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--example', description = 'Example argument')
parser.add_argument('--flag', action = 'store_true')
# ...
args.parse_args(parser) # Uses parser on CLI args
hackerargs will first use your ArgumentParser to parse known arguments,
then parse unknown CLI arguments in --{key} {val}
format.
Running python example.py --example text --unknown 1
, we get:
args = {'example': 'text', 'flag': False, 'unknown': 1}
Supporting argparse lets you create help messages for your scripts easily.
Priority during initialization
Hackerargs can be initialized with a YAML config file, argparser, and unknown command-line arguments in --{key} {val}
format.
During initialization, the order of priority is:
- (Lowest priority) argparse providing default values, when user does not specify
- YAML config
- (Highest priority) Command-line arguments specified by user
After initialization, setdefault cannot overwrite existing keys, and only write to new keys. Using setdefault prioritizes existing keys either from initialization or the earliest call of setdefault.
Initialization can be called with a mix of a YAML config file and/or argparser, using:
On the command line:
python train.py --config yaml_file
: Whenargs.parse_args()
is called, initialize args with yaml_file.--config
is a protected command-line option.
In python:
args.parse_args()
: Initialize by parsing command-line options in--{key} {val}
format.args.parse_args(yaml_file)
: Initialize using yaml file, then parse CLI options in--{key} {val}
format.args.parse_args(argparser)
: Initialize using argparser to parse first, then parse remaining CLI options in--{key} {val}
format.args.parse_args(argparser, yaml_file)
: Initialize using yaml file and ArgumentParser, then parse remaining CLI options in--{key} {val}
format.args.parse_args(yaml_file, argparser)
: Initialize using yaml file and ArgumentParser, then parse remaining CLI options in--{key} {val}
format.
Project details
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 hackerargs-0.0.1.tar.gz
.
File metadata
- Download URL: hackerargs-0.0.1.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cb2e9d42d8c4e9e3a3b475852ece2a8e976a2150e543cd6bf14f7989ae6c0335 |
|
MD5 | b660fe9af433b707d14bb5052974d36f |
|
BLAKE2b-256 | baca53689025716d06a118695016bf6bb8014812d06959e79e60a466e2a829e2 |
File details
Details for the file hackerargs-0.0.1-py3-none-any.whl
.
File metadata
- Download URL: hackerargs-0.0.1-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85ed9d7c29af1e4be54b47f0b65c146e837d8ad7fa1804266336e3854b706434 |
|
MD5 | bc7eb0cd780d31223947e485b3d6d0e9 |
|
BLAKE2b-256 | d72a08d3fc21f6e36b48d00fe8c2ee645aa1309c69ed51472e96ec5d1bf524e8 |