Skip to main content

hydra-typing

Typed dataclass configs for Hydra — so both you and your AI read the config easier.

PyPI

Your @hydra.main function receives an untyped DictConfig. With hydra-typing, it receives your @dataclass instance instead — full IDE autocompletion, mypy/pyright checking, and all Python types supported (Literal, Enum, Union, Path, datetime, nested dataclasses, List[Dataclass], Dict[str, Dataclass], etc.).

All Hydra features work unchanged — defaults: groups, ${} interpolation, CLI overrides, --multirun, sweepers, launchers, output management.

Install

pip install hydra-typing

One dependency: hydra-core.

Usage

Transparent patch (recommended) — keep your @hydra.main:

import hydra
import hydra_typing; hydra_typing.patch()

@hydra.main(config_path="conf", config_name="config", version_base=None)
def main(cfg: TrainConfig) -> None:
    # cfg is typed!  No DictConfig, no OmegaConf.
    print(cfg.model.hidden_dim)  # IDE autocompletion works

Explicit decorator:

from hydra_typing import hydra_main

@hydra_main(config_path="conf", config_name="config")
def main(cfg: TrainConfig) -> None:
    ...

Programmatic (notebooks, scripts):

from hydra_typing import load_config

cfg = load_config(TrainConfig, config_name="base",
                  overrides=["model=large", "lr=0.001"])

Features

  • Typed configs — real @dataclass instances, not DictConfig
  • Full Python type supportLiteral, Enum, Union, Path, datetime, nested dataclasses, List[Dataclass], Dict[str, Dataclass]
  • HydraConfig — typed access to Hydra's built-in runtime config (run.dir, job.name, overrides.task, etc.)
  • _target_ / instantiate — standard Hydra _target_ pattern works as a typed field
  • to_omegaconf() — 100% compatibility fallback: convert typed config back to OmegaConf DictConfig
  • Non-invasive — functions without type annotations pass through unchanged
  • Single filehydra_typing.py, ~700 lines, one dependency

Incremental adoption

No need to model everything upfront. Add types one field at a time:

import hydra_typing; hydra_typing.patch()

# Step 1: no types at all — everything still works
@hydra.main(...)
def main(cfg):                    # DictConfig, unchanged
    cfg.model.hidden_dim

# Step 2: type one field, leave the rest as Any (= DictConfig)
@dataclass
class TrainConfig:
    model: Any = None             # Any → DictConfig, cfg.model.hidden_dim still works
    lr: float = 3e-4              # validated as float, IDE-completes

# Step 3: tighten Any → dataclass when ready
@dataclass
class ModelConfig:
    hidden_dim: int = 256

@dataclass
class TrainConfig:
    model: ModelConfig = field(default_factory=ModelConfig)
    lr: float = 3e-4

Any fields keep the original DictConfig — so cfg.model.hidden_dim works the same before and after typing.

Extra YAML keys not in your dataclass are attached as instance attributes — cfg.whatever doesn't break. Opt into strict=True when you're ready to reject unknown keys.

Complex nested configs

@dataclass
class LayerConfig:
    type: Literal["attention", "mlp"] = "attention"
    dim: int = 256

@dataclass
class TrainConfig:
    layers: List[LayerConfig] = field(default_factory=lambda: [
        LayerConfig(type="attention", dim=256),
        LayerConfig(type="mlp", dim=512),
    ])

CLI overrides for nested collections:

# List elements by index
python train.py model.layers.0.dim=1024

# Dict elements by key
python train.py model.heads.attention.dim=512

# Append to list
python train.py +model.layers.2.type=conv +model.layers.2.dim=512

_target_ / instantiate

@dataclass
class LoRAConfig:
    _target_: str = "__main__.LoRAConfig"
    rank: int = 8
    alpha: int = 16

    def __post_init__(self):
        self.scaling = self.alpha / self.rank

# Deferred instantiate via OmegaConf round-trip (100% compat)
import hydra.utils
oc = hydra_typing.to_omegaconf(cfg.model.lora)
lora = hydra.utils.instantiate(oc)

HydraConfig — typed built-in config

@dataclass
class TrainConfig:
    hydra: HydraConfig = field(default_factory=HydraConfig)

# Auto-populated:
cfg.hydra.run.dir          # "outputs/2026-08-05/15-24-20"
cfg.hydra.job.name         # "train"
cfg.hydra.overrides.task   # ["model=large", "lr=0.001"]

vs Hydra

hydra hydra-typing
Config object DictConfig typed @dataclass
IDE autocomplete limited full
Literal, Union unsupported supported
Path, datetime unsupported supported
YAML composition yes yes (unchanged)
CLI overrides yes yes (unchanged)
--multirun yes yes (unchanged)
_target_ / instantiate yes yes
Output management yes yes (unchanged)

API

hydra_typing.patch()           # make @hydra.main typed (call once)
hydra_typing.hydra_main(...)   # explicit decorator
hydra_typing.load_config(...)  # programmatic (notebooks)
hydra_typing.to_plain(cfg)     # dataclass → dict
hydra_typing.to_omegaconf(cfg) # dataclass → OmegaConf DictConfig (100% compat)

About

This project was built to scratch a personal itch: I wanted Hydra's YAML composition and CLI, but with real typed configs I can trust my IDE with. I'm not yet writing the actual training code — but I want the config management to be clean from day one.

This code was written entirely by Claude Code (Anthropic) using the DeepSeek API. I acted as the product manager — specifying what the library should do, reviewing the output, and iterating. The implementation, tests, examples, and documentation were all generated by Claude.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hydra_typing-0.3.1.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hydra_typing-0.3.1-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file hydra_typing-0.3.1.tar.gz.

File metadata

  • Download URL: hydra_typing-0.3.1.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for hydra_typing-0.3.1.tar.gz
Algorithm Hash digest
SHA256 5f2aaebae6e785ef5d02f08dd4e3c8f11b6951786b8439b3affc8e7fc459846c
MD5 1053d091dddba656c4c869d799ac4969
BLAKE2b-256 4f282bdb21f8379bd6c33ecbe131143c7a2f1a078107fd9533f216c02bf8ab0c

See more details on using hashes here.

File details

Details for the file hydra_typing-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: hydra_typing-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for hydra_typing-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6046509920c33603b1cef7a7dcd967b5fa751dde184a4b6101de8404e9b15212
MD5 0070edd331d901b47c913ef61f072810
BLAKE2b-256 f2eff027d501e57066d0708aff200a954c28b79fa1b64efd5a8540c53b5ea9b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page