Usage

Installation

pip install configbase

Examples

Strongly Typed

from config import config

class MyClass:
    def __init__(self, a=3, b=3):
        self.a = a
        self.b = b

@config
class C:
    a: MyClass = MyClass()
    b: int = 5

c = C(a={"a": 1})
c.a.a
# Output:
1

Object-Persistence

print(C.from_yaml(c.to_yaml()))
# Output:
C(a={'a': 1, 'b': 2}, b=5)

Immutable

c.freeze()
c.b=1
# Output:
# RuntimeError: Can not set attribute b on frozen configuration ``C``.
c.unfreeze()
c.b=1
c.b
# Output:
1

Fingerprinting

from config import config, Stateless, Derived

@config
class C:
    a: Stateless[int] = 5
    b: int = 5
c = C()
c.uid
# Output:
'1cf3'
c.a=6
c.uid
# Output:
'1cf3'
c.a=5
c.uid
# Output:
'51fd'

Distributions

from config import config, Distribution, CategoricalDistribution, SearchSpace

@config
class A:
    d: float = 0.5

@config
class Master:
    a: A = A()
    d: float = 0.5

space = SearchSpace(
    {
        "a.d": Distribution(0, 1, n_bins=4),
        "d": CategoricalDistribution([Distribution(0, 0.1, n_bins=4), Distribution(0.9, 1, n_bins=4)]),
    }
)

m = Master()
m.sample(space)
# Output:
Master(a={'d': 0.0}, d=1.0)

Custom HPO Functions

def hpo_fn(name, dist: CategoricalDistribution | Distribution):
    return dist.random_sample()
m.sample(space, sample_fn=hpo_fn)
# Output:
Master(a={'d': 0.5}, d=0.925)

Expand Search Space

print(m.expand(space))
# Output:
[Master(a={'d': 0.0}, d=0.0), Master(a={'d': 0.0}, d=0.025), Master(a={'d': 0.0}, d=0.05), Master(a={'d': 0.0}, d=0.07500000000000001), Master(a={'d': 0.0}, d=0.1), Master(a={'d': 0.25}, d=0.0), Master(a={'d': 0.25}, d=0.025), Master(a={'d': 0.25}, d=0.05), Master(a={'d': 0.25}, d=0.07500000000000001), Master(a={'d': 0.25}, d=0.1), Master(a={'d': 0.5}, d=0.0), Master(a={'d': 0.5}, d=0.025), Master(a={'d': 0.5}, d=0.05), Master(a={'d': 0.5}, d=0.07500000000000001), Master(a={'d': 0.5}, d=0.1), Master(a={'d': 0.75}, d=0.0), Master(a={'d': 0.75}, d=0.025), Master(a={'d': 0.75}, d=0.05), Master(a={'d': 0.75}, d=0.07500000000000001), Master(a={'d': 0.75}, d=0.1), Master(a={'d': 1.0}, d=0.0), Master(a={'d': 1.0}, d=0.025), Master(a={'d': 1.0}, d=0.05), Master(a={'d': 1.0}, d=0.07500000000000001), Master(a={'d': 1.0}, d=0.1), Master(a={'d': 0.0}, d=0.9), Master(a={'d': 0.0}, d=0.925), Master(a={'d': 0.0}, d=0.95), Master(a={'d': 0.0}, d=0.975), Master(a={'d': 0.0}, d=1.0), Master(a={'d': 0.25}, d=0.9), Master(a={'d': 0.25}, d=0.925), Master(a={'d': 0.25}, d=0.95), Master(a={'d': 0.25}, d=0.975), Master(a={'d': 0.25}, d=1.0), Master(a={'d': 0.5}, d=0.9), Master(a={'d': 0.5}, d=0.925), Master(a={'d': 0.5}, d=0.95), Master(a={'d': 0.5}, d=0.975), Master(a={'d': 0.5}, d=1.0), Master(a={'d': 0.75}, d=0.9), Master(a={'d': 0.75}, d=0.925), Master(a={'d': 0.75}, d=0.95), Master(a={'d': 0.75}, d=0.975), Master(a={'d': 0.75}, d=1.0), Master(a={'d': 1.0}, d=0.9), Master(a={'d': 1.0}, d=0.925), Master(a={'d': 1.0}, d=0.95), Master(a={'d': 1.0}, d=0.975), Master(a={'d': 1.0}, d=1.0)]