Table of Contents
Generate command line options from dataclasses.
# config.py
from dataclasses import dataclass, asdict, field
from smile_config import from_dataclass
@dataclass
class Train:
"""Train config."""
batch_size: int = 64
@dataclass
class ML:
lr: Annotated[float, dict(help="learning rate", type=float)] = 0.001
train: Train = Train()
cc: list[int] = field(default_factory=lambda: [10])
@dataclass
class Example:
"""Example config."""
ml: ML = ML()
x: bool = True
a: int | None = None
config = from_dataclass(Example()).config
print(config)
# If autocomplete is not working, try to add the following line to your config file:
from typing import cast
config = cast(Example, config)
You can access the config as namedtuple.
> python config.py --ml.cc 10 10 --ml.lr 0.001 --no-x --a "1"
Example(ml=ML(lr=0.001, train=Train(batch_size=64), cc=[10, 10]), x=False, a=1)
Also, auto generate help message with default value.
> python config.py --help
Usage: config.py [-h] [--ml.lr float] [--ml.train.batch_size int] [--ml.cc int [int ...]] [--x | --no-x] [--a int]
Example config.
Options:
-h, --help show this help message and exit
--x, --no-x - (default: True)
--a int - (default: None)
Ml:
--ml.lr float learning rate (default: 0.001)
--ml.cc int [int ...]
- (default: [10])
Ml.Train:
--ml.train.batch_size int
- (default: 64)
Install
pip install -U smile_config
Usage
Dataclass to command line options
Simple types
Everything that argpase can handle. int, float, str, bool, and callable object.
@dataclass
class Simple:
a: int = 1
b: float = 2.0
c: str = "hello"
d: bool = False
e: list[int] = field(default_factory=lambda: [10])
Will convert to:
parser.add_argument("--a", help="-", type=int, default=1)
parser.add_argument("--b", help="-", type=float, default=2.0)
parser.add_argument("--c", help="-", type=str, default="hello")
parser.add_argument("--d", help="-", type=bool, default=False, action="store_true")
parser.add_argument("--e", help="-", type=int, default=[10], nargs="+")
Complex types
Smile config uses Annotation to handle complex types, which will pass
the second argument to parser.add_argument.
@dataclass
class C:
x: Annotated[int, "Helps for x."] = 1
See the logic here:
The first argument is the type, e.g. int.
if the second argument is str, e.g. s, it will be passed as parser.add_argument("--x", help=s, ...).
If the second argument is a list, e.g. args, it will be passed as parser.add_argument("--x", ..., *args).
If the second argument is a dict, e.g. kwds, it will be passed as parser.add_argument("--x", ..., **kwds).
Private fields
Fields that start with _ will be ignored. Thus, please initialize it by default or in `__post_init__`.
Nested dataclass
Of course! It does support nested dataclass.
@dataclass
class A:
a: int = 1
@dataclass
class B:
a: A = A()
@dataclass
class C:
a: A = A()
b: B = B()
c: int = 0
_d: str = "private _d"
print(from_dataclass(C()).config)
# Output:
# C(a=A(a=1), b=B(a=A(a=1)), c=0, _d="private _d")
APIs
Smile config provides four APIs:
class Config:
# the dataclass dict
self.conf
# the dataclass
self.config
# Generate command line options from dataclass.
# For formatter: `from rich_argparse import RichHelpFormatter`
# `ns`: namespaces for types.
def from_dataclass(dc: Dataclass, *, formatter: HelpFormatter = RichHelpFormatter, ns: dict | None = None) -> Config:...
# Convert dict to an existing dataclass
def from_dict(dc: Type[Dataclass], d: dict) -> Dataclass:...
# Merge a dict with an existing dataclass instance
def merge_dict(dc: Dataclass, d: dict) -> Dataclass:...
Example
@dataclass
class Eg:
a: int = 1
b: bool = False
conf = from_dataclass(Eg())
print(conf) # Config
# output: Eg(a=1, b=False)
print(conf.conf) # dict
# output: {'a': 1, 'b': False}
print(conf.config) # Eg
# output: Eg(a=1, b=False)
conf_dc = from_dict(Eg, {"a": 2, "b": True}) # Type[Eg] -> dict -> Eg
print(conf_dc)
# output: Eg(a=2, b=True)
conf_merge = merge_dict(conf_dc, {"a": 3}) # Eg -> dict -> Eg
print(conf_merge)
# output: Eg(a=3, b=True)
Metadata
Release files for smile-config 0.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| smile-config-0.12.0.tar.gz | 9.9 kB | Without provenance | Details for smile-config-0.12.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| smile_config-0.12.0-py3-none-any.whl | Python 3 | none | any | Details for smile_config-0.12.0-py3-none-any.whl |
Total release size: 21.2 kB
Release files / smile-config-0.12.0.tar.gz
| Download URL | smile-config-0.12.0.tar.gz |
|---|---|
| Size | 9.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f19523a0bccf1fea370ce5ae3ae97dc5631410892212b6cd318fe664cbd465e
|
|
BLAKE2b-256 checksum How to use checksums |
c70b5c79c7ce6fffd37c61e0263797d75f3e1b9a37ce08b9a9cf64b8d7c6e36d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.9
|
Release files / smile_config-0.12.0-py3-none-any.whl
| Download URL | smile_config-0.12.0-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d2886f12e1a39aba41fa0b4f8fa5e68a00093914a3cf489116f569f864e5db6
|
|
BLAKE2b-256 checksum How to use checksums |
ce3394134171ed6a61886c9e060f35919e52b405ee8d7e9d95bb5f77f270c676
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.9
|
Security for smile-config 0.12.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.