Metadata-Version: 2.4
Name: tonga-config
Version: 0.1.0
Summary: Lightweight extraction of FromParams/Registrable from ai2-tango (import as `tonga`)
Author-email: Luke Gessler <lukegessler@gmail.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/lgessler/tonga
Project-URL: Repository, https://github.com/lgessler/tonga
Project-URL: Issues, https://github.com/lgessler/tonga/issues
Keywords: config,registry,from_params,jsonnet,dependency-injection,tango,allennlp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: rjsonnet<1.0,>=0.4
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Dynamic: license-file

# tonga

A lightweight extraction of the config-driven object construction system from [ai2-tango](https://github.com/allenai/tango). Provides `FromParams`, `Registrable`, `Lazy`, and `Params` with minimal dependencies (just `rjsonnet`), removing all Step/Workspace/integration machinery.

## Installation

```bash
pip install tonga-config
```

The distribution name on PyPI is `tonga-config`, but the import name is `tonga`:

```python
from tonga import FromParams, Registrable, Lazy, Params
```

For development:

```bash
pip install -e ".[dev]"
```

## Usage

### Registrable classes

Define a base class and register subclasses by name. Instantiate them from config dicts using `from_params`:

```python
from tonga import Registrable, Params

class Encoder(Registrable):
    pass

@Encoder.register("lstm")
class LSTMEncoder(Encoder):
    def __init__(self, input_dim: int, hidden_dim: int, num_layers: int = 1):
        self.input_dim = input_dim
        self.hidden_dim = hidden_dim
        self.num_layers = num_layers

encoder = Encoder.from_params(Params({
    "type": "lstm",
    "input_dim": 128,
    "hidden_dim": 256,
    "num_layers": 2,
}))
```

### Loading configs from jsonnet files

```python
from tonga import Params

params = Params.from_file("config.jsonnet")
model = Model.from_params(params)
```

### Nested construction

Constructor arguments that are themselves `FromParams`/`Registrable` subclasses are constructed recursively:

```python
from tonga import Registrable, Params

class Activation(Registrable):
    pass

@Activation.register("relu")
class ReLU(Activation):
    pass

@Activation.register("gelu")
class GELU(Activation):
    pass

class FeedForward(Registrable):
    pass

@FeedForward.register("linear")
class Linear(FeedForward):
    def __init__(self, input_dim: int, output_dim: int, activation: Activation):
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.activation = activation

ff = FeedForward.from_params(Params({
    "type": "linear",
    "input_dim": 128,
    "output_dim": 64,
    "activation": {"type": "gelu"},
}))
assert isinstance(ff.activation, GELU)
```

### Lazy construction

Use `Lazy` when one constructor argument depends on another:

```python
from tonga import Registrable, Lazy, Params

class Optimizer(Registrable):
    pass

@Optimizer.register("sgd")
class SGD(Optimizer):
    def __init__(self, lr: float, params: list):
        self.lr = lr
        self.params = params

class Trainer(Registrable):
    pass

@Trainer.register("default")
class DefaultTrainer(Trainer):
    @classmethod
    def from_parts(cls, model_params: list, lazy_optimizer: Lazy[Optimizer]):
        trainer = cls()
        trainer.optimizer = lazy_optimizer.construct(params=model_params)
        return trainer
```

### FromParams without registration

Classes can use `FromParams` directly without a registry when you don't need polymorphic dispatch:

```python
from tonga import FromParams

class Config(FromParams):
    def __init__(self, learning_rate: float, batch_size: int = 32):
        self.learning_rate = learning_rate
        self.batch_size = batch_size

config = Config.from_params({"learning_rate": 0.001})
assert config.batch_size == 32
```

## Acknowledgements

Tonga is a derivative work of [ai2-tango](https://github.com/allenai/tango) by
the Allen Institute for Artificial Intelligence. The `FromParams`,
`Registrable`, `Lazy`, and `Params` classes were extracted and adapted from
that project. All credit for the original design goes to the AI2 Tango authors
and, before them, the [AllenNLP](https://github.com/allenai/allennlp) team.

## License

Tonga is licensed under the [Apache License, Version 2.0](LICENSE). See the
[NOTICE](NOTICE) file for upstream attribution.

