Skip to main content

Table of Contents

  1. Install
  2. Usage
    1. Dataclass to command line options
      1. Simple types
      2. Complex types
      3. Private fields
      4. Nested dataclass
    2. APIs
      1. Example

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)

Source distribution for smile-config 0.12.0
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)

Table of built distributions (wheels) for smile-config 0.12.0
File Interpreter ABI Platform Actions
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page