Metadata-Version: 2.4
Name: hydrette
Version: 0.1.0
Summary: A lightweight Hydra-style configuration management library
License-Expression: MIT
Project-URL: Repository, https://github.com/chr0nixz/hydrette
Project-URL: Issues, https://github.com/chr0nixz/hydrette/issues
Keywords: hydra,configuration,yaml,interpolation,override
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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 :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML>=5.4
Provides-Extra: toml
Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "toml"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# hydrette

Lightweight Hydra-style configuration management for Python.

Core dependency: **PyYAML**. Optional: **tomli** (for TOML on Python < 3.11).

## Features

- **Config composition** — `defaults` list + config groups, like Hydra
- **Variable interpolation** — `${key.path}`, `${env:VAR}`, `${now:%Y-%m-%d}`
- **CLI overrides** — `key=val`, `+key=val` (add), `++key=val` (force), `~key` (delete)
- **`@main` decorator** — entrypoint with automatic CLI parsing
- **Structured config** — dataclass schema validation (warning / strict)
- **`instantiate()`** — build objects from `_target_` configs
- **Dot & subscript access** — `cfg.db.host` == `cfg["db"]["host"]`
- **YAML & TOML** — `.yaml`, `.yml`, `.toml` config files; mixed-format projects supported

## Quick Start

### Installation

```bash
pip install -e .
```

### Project structure

```
conf/
├── config.yaml          # root config
├── db/
│   ├── mysql.yaml
│   └── postgres.yaml
└── model/
    ├── resnet.yaml
    └── vgg.yaml
```

### Root config (`conf/config.yaml`)

```yaml
defaults:
  - db: mysql
  - model: resnet

app_name: demo
db_url: ${db.host}:${db.port}
```

### Group config (`conf/db/mysql.yaml`)

```yaml
host: localhost
port: 3306
```

### Using `compose()`

```python
from hydrette import compose

cfg = compose("conf")
print(cfg.db.host)     # "localhost"
print(cfg.db_url)      # "localhost:3306"
```

### CLI overrides

```python
from hydrette import compose

cfg = compose("conf", overrides=["db=postgres", "model.lr=0.001"])
```

From command line with `@main`:

```bash
python app.py -- db=postgres model.lr=0.001
```

### `@main` decorator

```python
from hydrette import main, Config

@main(config_path="conf")
def app(cfg: Config) -> None:
    print(cfg.db.host)

if __name__ == "__main__":
    app()
```

### Variable interpolation

| Syntax | Description |
|--------|-------------|
| `${key.path}` | Reference another config value |
| `${env:VAR}` | Environment variable |
| `${env:VAR,default}` | Env var with default |
| `${now:%Y-%m-%d}` | Current time (strftime) |
| `${${prefix}_lr}` | Nested interpolation |

### Custom resolvers

```python
from hydrette import register_resolver

register_resolver("greet", lambda name: f"Hello, {name}!")

# In YAML: message: ${greet:World}
```

### Schema validation

```python
from dataclasses import dataclass
from hydrette import register_schema, validate_config, Config

@dataclass
class TrainCfg:
    lr: float = 0.01
    epochs: int = 10

register_schema("train", TrainCfg)

cfg = compose("conf")
validate_config(cfg)          # warning mode (default)
validate_config(cfg, strict=True)  # raise on errors
```

### `instantiate()`

```python
from hydrette import instantiate, Config

cfg = Config({
    "_target_": "mymodule:MyClass",
    "x": 1,
    "y": 2,
})
obj = instantiate(cfg)
```

## `_self_` position

In the `defaults` list, `_self_` controls where the root config's own keys
are merged into the composition chain:

- **Explicit**: place `_self_` wherever you want
- **Implicit** (default): `_self_` is appended at the end, so root keys
  override group keys at the same path

Group configs are **namespaced** under their group name:
`db/mysql.yaml` → `cfg.db.host`, not `cfg.host`.

## Override syntax

| Syntax | Meaning |
|--------|---------|
| `key=val` | Set existing key |
| `+key=val` | Add new key (error if exists) |
| `++key=val` | Force set (add or overwrite) |
| `~key` | Delete key |
| `db=postgres` | Switch config group |

## CLI flags

| Flag | Description |
|------|-------------|
| `--quiet` | Suppress loading tree output |
| `--help` | Print config preview and usage |
| `HYDRETTE_QUIET=1` | Environment variable alternative |

## File formats

hydrette supports both **YAML** (`.yaml` / `.yml`) and **TOML** (`.toml`) config files.
You can even mix formats within a project — e.g. a YAML root with TOML group configs.

### Extension probing

When `config_name` is given without an extension, hydrette probes in order:
`.yaml` → `.yml` → `.toml`. If multiple files match, an ambiguity error is raised.

```bash
# Only config.toml exists → auto-detected
python app.py

# Explicit TOML root
python app.py  # compose("conf", config_name="config.toml")
```

### TOML defaults syntax

YAML uses `- db: mysql` for defaults. In TOML, use inline tables:

```toml
defaults = [{ db = "mysql" }]
```

Override directives in TOML:

```toml
# Quoted key (same as YAML "override db: postgres")
defaults = [{ db = "mysql" }, { "override db" = "postgres" }]

# Structured form (cleaner)
defaults = [
  { db = "mysql" },
  { group = "db", name = "postgres", override = true },
]
```

### Installing TOML support

Python 3.11+ includes `tomllib` in the standard library — no extra install needed.

For Python 3.9–3.10:

```bash
pip install hydrette[toml]
```

If you load a `.toml` file without the dependency installed, hydrette will show
a clear error message with the install command.

## License

MIT
