Skip to main content

Yaml to Dataclass parser for Config files (Rust-powered for performance)

Project description

Heracless

Heracless

Type-safe YAML configuration management for Python

Transform your YAML config files into strongly-typed Python dataclasses with full IDE autocomplete support

PyPI version Python Version Rust License: MIT Tests codecov mypy Documentation

InstallationQuick StartDocumentationExamples


Why Heracless?

Stop wrestling with dictionaries and string keys. Heracless automatically converts your YAML configuration files into Python dataclasses with full type safety and IDE autocomplete support. Plus it's written in Rust for blazing-fast performance.

# WITHOUT Heracless - prone to typos, no autocomplete
config = yaml.load(open("config.yaml"))
db_host = config["database"]["host"]  # Runtime errors waiting to happen
db_port = config["databse"]["port"]   # Typo goes unnoticed!

# WITH Heracless - type-safe, autocomplete, catch errors at write-time
config = load_config()
db_host = config.database.host  # Autocomplete works!
db_port = config.database.port  # Typos caught by IDE/mypy

Features

  • Automatic Type Generation - Generates .pyi stub files for full IDE support
  • Type Safety - Catch configuration errors at development time, not runtime
  • Zero Boilerplate - No manual dataclass definitions needed
  • IDE Autocomplete - Full IntelliSense/autocomplete for all config values
  • Immutable by Default - Frozen dataclasses prevent accidental modifications
  • Rust-Powered Performance - Native Rust backend for blazing-fast YAML parsing and stub generation

Installation

From PyPI (Recommended)

pip install heracless

From Source

git clone https://github.com/felixscode/heracless.git
cd heracless
pip install -e .

Requirements

Python Version Status
3.10 - 3.13 Fully Supported
3.9 and below Not Supported

Dependencies: PyYAML, black, art

Note: Prebuilt Rust wheels are available for Linux, macOS, and Windows. No Rust installation required!


Quick Start

1. Create your configuration file

Create a config.yaml file with your settings:

# config.yaml
database:
  host: localhost
  port: 5432
  name: myapp_db
  credentials:
    username: admin
    password: secret123 # don't use this in production

api:
  base_url: https://api.example.com
  timeout: 30
  retries: 3

features:
  enable_caching: true
  max_cache_size: 1000

2. Set up the config loader

Create a load_config.py file in your project:

# src/myproject/load_config.py
from pathlib import Path
from typing import TypeVar
from heracless import load_config as _load_config

# Point to your config file
CONFIG_YAML_PATH = Path(__file__).parent.parent / "config.yaml"

Config = TypeVar("Config")

def load_config(config_path: Path | str = CONFIG_YAML_PATH,
                frozen: bool = True,
                stub_dump: bool = True) -> Config:
    """Load configuration and generate type stubs."""
    file_path = Path(__file__).resolve() if stub_dump else None
    return _load_config(config_path, file_path, frozen=frozen)

3. Use your config with full type safety

# src/myproject/main.py
from myproject.load_config import load_config

# Load config - first run generates load_config.pyi with types!
config = load_config()

# Access config with autocomplete and type checking
print(f"Connecting to {config.database.host}:{config.database.port}")
print(f"Database: {config.database.name}")
print(f"API URL: {config.api.base_url}")
print(f"Caching enabled: {config.features.enable_caching}")

Output:

Connecting to localhost:5432
Database: myapp_db
API URL: https://api.example.com
Caching enabled: True

Generated Type Stub Example

After the first run, Heracless automatically generates a load_config.pyi file:

# load_config.pyi (auto-generated)
from dataclasses import dataclass
from typing import TypeVar

@dataclass(frozen=True)
class Credentials:
    username: str
    password: str

@dataclass(frozen=True)
class Database:
    host: str
    port: int
    name: str
    credentials: Credentials

@dataclass(frozen=True)
class Api:
    base_url: str
    timeout: int
    retries: int

@dataclass(frozen=True)
class Features:
    enable_caching: bool
    max_cache_size: int

@dataclass(frozen=True)
class Config:
    database: Database
    api: Api
    features: Features

This stub file enables full IDE autocomplete and type checking


Usage Examples

Basic Configuration Loading

from myproject.load_config import load_config

# Load with defaults (frozen, with stub generation)
config = load_config()

# Access nested values with autocomplete
db_url = f"{config.database.host}:{config.database.port}"

Mutable Configuration

# Load mutable config for testing or dynamic updates
config = load_config(frozen=False)

# Modify values (only works with frozen=False)
config.database.host = "192.168.1.100"

Converting to Dictionary

from heracless.utils.helper import as_dict

config = load_config()
config_dict = as_dict(config)

# Now a regular Python dictionary
print(config_dict["database"]["host"])  # localhost

Creating Config from Dictionary

from heracless.utils.helper import from_dict

config_dict = {
    "database": {
        "host": "localhost",
        "port": 5432
    },
    "api": {
        "base_url": "https://api.example.com",
        "timeout": 30
    }
}

config = from_dict(config_dict, frozen=True)
print(config.database.host)  # localhost (with type checking!)

Updating Configuration Values

from heracless.utils.helper import mutate_config

config = load_config()

# Create a new config with updated value (immutable pattern)
new_config = mutate_config(config, "database.host", "production-db.example.com")

print(config.database.host)      # localhost (original unchanged)
print(new_config.database.host)  # production-db.example.com

CLI Tool Usage

Heracless includes a CLI tool for generating stub files and validating configs:

# Generate stub file from config
python -m heracless config.yaml --parse types.pyi

# Dry run (validate config without generating files)
python -m heracless config.yaml --dry

# Show help
python -m heracless --help

Project Structure Example

Here's a recommended project structure:

my_project/
├── src/
│   └── myproject/
│       ├── __init__.py
│       ├── main.py
│       └── config/
│           ├── __init__.py
│           ├── load_config.py      # Your config loader
│           └── load_config.pyi     # Auto-generated types
├── config/
│   ├── config.yaml                 # Main config
│   ├── config.dev.yaml             # Development overrides
│   └── config.prod.yaml            # Production overrides
├── tests/
│   └── test_config.py
├── pyproject.toml
└── README.md

Troubleshooting

Issue: IDE not showing autocomplete

Solutions:

  1. Ensure the .pyi file exists next to your load_config.py
  2. Reload your IDE/editor window
  3. Check that your language server is running (VSCode: check Python extension)
  4. For PyCharm: File → Invalidate Caches → Restart

Issue: TypeError: 'Config' object is immutable

Solution: This is by design (frozen dataclass). To modify configs:

  • Use mutate_config() helper to create updated copies
  • Or load with frozen=False for mutable configs (not recommended)

Issue: YAML parsing errors

Solution: Ensure your YAML is valid:

# Validate YAML syntax
python -c "import yaml; yaml.safe_load(open('config.yaml'))"

API Reference

Core Functions

load_config(config_path, file_path, frozen)

Load a YAML configuration file and convert it to a typed dataclass.

Parameters:

  • config_path (Path | str): Path to the YAML configuration file
  • file_path (Path | str | None): Path where stub file should be generated (None to skip)
  • frozen (bool): Whether the resulting dataclass should be immutable (default: True)

Returns: Config dataclass with attributes matching your YAML structure

Raises:

  • FileNotFoundError: If config file doesn't exist
  • yaml.YAMLError: If YAML file is malformed

Helper Functions

mutate_config(config, name, value)

Create a new config with an updated value (immutable pattern).

from heracless.utils.helper import mutate_config

config = load_config()
new_config = mutate_config(config, "database.port", 3306)

as_dict(config)

Convert a Config dataclass to a nested dictionary.

from heracless.utils.helper import as_dict

config = load_config()
config_dict = as_dict(config)  # Returns: dict

from_dict(config_dict, frozen)

Create a Config dataclass from a dictionary.

from heracless.utils.helper import from_dict

config_dict = {"database": {"host": "localhost"}}
config = from_dict(config_dict, frozen=True)

Contributing

Contributions are welcome! Here's how you can help:

Development Setup

# Clone the repository
git clone https://github.com/felixscode/heracless.git
cd heracless

# Install with development dependencies
pip install -e .[dev]

# Run tests
pytest

# Run type checking
mypy heracless

# Run code formatting
black heracless tests

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=heracless --cov-report=html

# Run specific test file
pytest tests/test_config.py

Development Dependencies

Install development dependencies with:

pip install -e .[dev]

This includes:

  • pytest - Testing framework
  • pytest-cov - Coverage reporting
  • mypy - Static type checking
  • types-PyYAML - Type stubs for PyYAML

Documentation Development

To work on the documentation:

# Install documentation dependencies
pip install -e .[doc]

# Serve documentation locally
mkdocs serve

# Build documentation
mkdocs build

Reporting Issues

Found a bug or have a feature request? Open an issue on GitHub.

Please include:

  • Heracless version (pip show heracless)
  • Python version
  • Operating system
  • Minimal reproducible example
  • Expected vs actual behavior

Roadmap

Current Version: 0.5.1

Planned Features

  • Config variants - Support for environment-specific configs (dev/staging/prod)
  • Environment variable interpolation - ${ENV_VAR} syntax in YAML

License

Heracless is released under the MIT License. See LICENSE file for details.

MIT License

Copyright (c) 2023 Felix Schelling

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

TL;DR: You can freely use, modify, and distribute this software, even for commercial purposes.


Links & Resources


Author

Felix Schelling


If Heracless helps your project, consider giving it a star on GitHub!

Back to Top

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

heracless-0.5.1-cp313-cp313-win_amd64.whl (875.4 kB view details)

Uploaded CPython 3.13Windows x86-64

heracless-0.5.1-cp313-cp313-manylinux_2_34_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

heracless-0.5.1-cp313-cp313-macosx_11_0_arm64.whl (977.0 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

heracless-0.5.1-cp312-cp312-win_amd64.whl (876.2 kB view details)

Uploaded CPython 3.12Windows x86-64

heracless-0.5.1-cp312-cp312-manylinux_2_34_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

heracless-0.5.1-cp312-cp312-macosx_11_0_arm64.whl (977.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

heracless-0.5.1-cp311-cp311-win_amd64.whl (876.1 kB view details)

Uploaded CPython 3.11Windows x86-64

heracless-0.5.1-cp311-cp311-manylinux_2_34_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

heracless-0.5.1-cp311-cp311-macosx_11_0_arm64.whl (978.0 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

heracless-0.5.1-cp310-cp310-win_amd64.whl (876.0 kB view details)

Uploaded CPython 3.10Windows x86-64

heracless-0.5.1-cp310-cp310-manylinux_2_34_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

heracless-0.5.1-cp310-cp310-macosx_11_0_arm64.whl (977.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file heracless-0.5.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: heracless-0.5.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 875.4 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for heracless-0.5.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 afca2333b611762864e66806863870704d6b1a638e3a9f4404c1a2877a847fbd
MD5 080f4c6cce043699449c936585834025
BLAKE2b-256 1d274a410a33ac9d1c6901875d320eb1a232e18f563ca7aca7b9ab669ddd3922

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 ba476422cfa0fd857876a37d09a9b47b4ab132f42174c6643e87b49185fb88c2
MD5 1c5e2044a2cafc50770829476b750b3c
BLAKE2b-256 bdf67fe4e2dc8aaeee5f7925c4cda21bb690a804c90eb70753edbcffc0d92d5a

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 61fb6eaf21cd86dccfaed25e68e250bb3dd6e89f89bb3576d383cce13bc6a93a
MD5 340f45a49eda549462725e1b4003e589
BLAKE2b-256 5ee3d2857c82066e70b3caa204d11100d64ff68cc573a26e404ef70d1066f143

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: heracless-0.5.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 876.2 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for heracless-0.5.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6f64c398c6854b2d9d16cf4aef5cee9e2041a38ec2f2f1a90b5405a277d97f3c
MD5 9b8bbc3cebed83aa1ec0ff6f23e134dc
BLAKE2b-256 994ef16b8f410c5fe0c61e5702c7f9dd7ab2646bb8acf0f35c3e7381c02781d1

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 0ca2aabd06da1ca8d8cbe521bcc2907e02bf98c2dc818a2ef3ec2091466c55d0
MD5 57433a33d2342f5a498815fa89fb8596
BLAKE2b-256 30c4e67961a0ff423a1cbbca8a43e65946b96b151036c4522f3106aa2cf56d51

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2bf6cbd2920942d9917c0c545917dc42efe4dac9ad9c465609bfbf6031b01c9b
MD5 68bfae0b7d6416f6814ad2cb5fd0468c
BLAKE2b-256 4ba5e0595c8606f29eb9ef67cd83c9f2f6c432cb0db558ae17c8e3a9855355c0

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: heracless-0.5.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 876.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for heracless-0.5.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 78b434a7c469f5e59bdd9ddf01bd2239aac7f28851d9023cb248ca3e1ead9c12
MD5 e7be4e5f5fb47e2cf61a93c58bbd558d
BLAKE2b-256 897b123261f92b38844ee891408aec5854966738430e627fdc66aed9dd803601

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d385d1a7e8d85329782bd0aa42b714ac4b0e283661d2b438ebb6254ca1230ac0
MD5 fdb84deda55a453ab1001563b0b51117
BLAKE2b-256 6f431f3aeda954d7ae7dc7a197392bbee053bd3b52ca280584888c9d8e2d1e08

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 65a24bb960bd8e29304dd7656a1b0c291abc874af358552dd45acd244e0ecf01
MD5 ddd233263b1e84b91e14897edeca290b
BLAKE2b-256 99d2a939844867fab05a2b580ed0611350399a4648fe6fd4994da59b108913c2

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: heracless-0.5.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 876.0 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for heracless-0.5.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 f4c7b7a58ef25356f34e7d1b9d17a55e66b5bc01238a842e3dad2540d8821356
MD5 b04371601a8c557816ad336d0bb13cdf
BLAKE2b-256 f970e9fe77cff0c48933fd5dbb367719fc0f7d38eb13c8da05742b37085b3d8a

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 5b1ffc3e22cd38921c33b402ab836e11010e11b23cbaf0e75886395fe8220edc
MD5 6020e553903bf35c7dbfce7c3bf1d59c
BLAKE2b-256 548a6749068e41ff216b08253ecffa8d495bac5eb65d12665cf53187880c2f36

See more details on using hashes here.

File details

Details for the file heracless-0.5.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for heracless-0.5.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 04c8aea56743071cfa77c0fe52de5ca5183939d6af86dc86b3301205b6890a5b
MD5 e1e45f3436a52f5285e49a0660cadecc
BLAKE2b-256 b4f69f0a26853dc40ee788f0ffdaa596cd3861e933dc8b37ac095343152e09b6

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