Skip to main content

YAML Data Class Config

Test CodeQL Code Coverage Maintainability Dependabot Python versions PyPI - Downloads X URL

This project helps you to import config file writen by YAML to Python Data Classes.

📖 Migration Guide

Upgrading from version 1.x? See the Migration Guide for step-by-step instructions to migrate to version 2.x.

Advantage

  1. Type safe import from YAML to Data Classes
  2. Global access and easy unit testing

1. Type safe import from YAML to Data classes

When using pyyaml to import YAML, values be dict and list objects. Using dict or list object will cause such confuses:

  • Reference non exist properties for unexpected instance type
  • Typo of index or key name

To prevent these confuse, one of good way is to use object as model, and python has a good module Data Classes for this purpose.

2. Global access and easy unit testing

You will want to refer config as global because it's troublesome to pass config value as argument over and over like a bucket brigade.

However, when unit testing, if YAML file was loaded automatically on importing global definition, you will face problem that you can't replace config YAML file with the one for unit testing. YAML Data Class Config can divide timings between definition global instance and loading YAML file so you can replace YAML file for unit testing.

Modern Python Features

This library leverages modern Python features for better type safety and developer experience:

  • Modern Union Syntax: Uses str | None instead of Union[str, None] (Python 3.10+)
  • Future Annotations: Uses from __future__ import annotations for improved type hint evaluation
  • Keyword-Only Arguments: Functions use * to enforce keyword-only arguments for better API clarity
  • Type Safety: Full mypy compliance with strict mode enabled
  • Runtime Type Checking: Proper handling of type annotations at runtime for dataclass serialization

Quickstart

1. Install

pip install yamldataclassconfig

2. Prepare config YAML file

Put config.yml YAML Data class Config loads config.yml on Python execution directory by default.

property_a: 1
property_b: '2'
part_config:
  property_c: '2019-06-25 13:33:30'

3. Create config class

Anywhere is OK, for example, I prefer to place on myproduct/config.py

from dataclasses import dataclass
from dataclasses import field
from datetime import datetime

from dataclasses_json import DataClassJsonMixin
from marshmallow import fields

from yamldataclassconfig.config import YamlDataClassConfig


@dataclass
class PartConfig(DataClassJsonMixin):
    property_c: datetime = field(
        metadata={
            "dataclasses_json": {
                "encoder": datetime.isoformat,
                "decoder": datetime.fromisoformat,
                "mm_field": fields.DateTime(format="iso"),
            },
        },
    )


@dataclass
class Config(YamlDataClassConfig):
    property_a: int
    property_b: str
    part_config: PartConfig = field(
        metadata={"dataclasses_json": {"mm_field": PartConfig}},
    )

4. Define as global

Also, anywhere is OK, for example, I prefer to place on myproduct/__init__.py

from myproduct.config import Config

CONFIG: Config = Config.create()

5. Call load before reference config value

from myproduct import CONFIG


def main() -> None:
    CONFIG.load()
    print(CONFIG.property_a)
    print(CONFIG.property_b)
    if CONFIG.part_config is not None:
        print(CONFIG.part_config.property_c)


if __name__ == '__main__':
    main()

How do I...

Fix path to yaml file independent on the Python execution directory?

override FILE_PATH property.

Ex:

from dataclasses import dataclass
from dataclasses import field
from pathlib import Path

from yamldataclassconfig import build_path
from yamldataclassconfig.config import YamlDataClassConfig


@dataclass
class Config(YamlDataClassConfig):
    some_property: str
    # ...

    FILE_PATH: str = field(
        init=False,
        default=build_path(Path(__file__).parent / "config.yml"),
    )

Switch target YAML config file to the one for unit testing?

When setup on unit testing, you can call Config.load() with argument.

Note: The path_is_absolute parameter must now be passed as a keyword argument due to API improvements in version 1.5.0.

Case when unittest:

from pathlib import Path
import unittest

from yourproduct import CONFIG

class ConfigurableTestCase(unittest.TestCase):
    def setUp(self) -> None:
        CONFIG.load(Path('path/to/yaml'))

Case when pytest:

from pathlib import Path
from typing import Generator

import pytest

from yourproduct import CONFIG

@pytest.fixture
def yaml_config() -> Generator[None, None, None]:
    CONFIG.load(Path('path/to/yaml'))
    yield

def test_something(yaml_config: None) -> None:
    """test something"""

Use path to YAML config file as same as production when test?

fixturefilehandler can replace config.yml with tests/config.yml.dist easily. Please call all DeployerFactory.create with YamlConfigFilePathBuilder instance argument to create ConfigDeployer. Then, set target directory which config.yml should be placed into path_target_directory.

Case when unittest:

from pathlib import Path
import unittest

from fixturefilehandler.factories import DeployerFactory
from fixturefilehandler.file_paths import YamlConfigFilePathBuilder

from yourproduct import CONFIG


ConfigDeployer = DeployerFactory.create(YamlConfigFilePathBuilder(path_target_directory=Path(__file__).parent.parent))


class ConfigurableTestCase(unittest.TestCase):
    def setUp(self) -> None:
        ConfigDeployer.setup()
        CONFIG.load()

    def doCleanups(self) -> None:
        ConfigDeployer.teardown()

Case when pytest:

from pathlib import Path
from typing import Generator

import pytest
from fixturefilehandler.factories import DeployerFactory
from fixturefilehandler.file_paths import YamlConfigFilePathBuilder

from yourproduct import CONFIG


ConfigDeployer = DeployerFactory.create(YamlConfigFilePathBuilder(path_target_directory=Path(__file__).parent.parent))


@pytest.fixture
def yaml_config() -> Generator[None, None, None]:
    ConfigDeployer.setup()
    CONFIG.load()
    yield
    ConfigDeployer.teardown()


def test_something(yaml_config: None) -> None:
    """test something"""

Metadata

Release files for yamldataclassconfig 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for yamldataclassconfig 2.1.0
File Size Uploaded Provenance
yamldataclassconfig-2.1.0.tar.gz 30.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for yamldataclassconfig 2.1.0
File Interpreter ABI Platform
yamldataclassconfig-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.6 kB

Release files / yamldataclassconfig-2.1.0.tar.gz

Download URL yamldataclassconfig-2.1.0.tar.gz
Size 30.1 kB
Tags Source
SHA-256 checksum
How to use checksums
99dca40069f765e80d9580265a66dcc6b2a1480612b94aca10aa48ac32056d36
BLAKE2b-256 checksum
How to use checksums
532204eac0ea10ff32c39143d171f0ffe566e068bb66a715b7124b53b0ae920d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / yamldataclassconfig-2.1.0-py3-none-any.whl

Download URL yamldataclassconfig-2.1.0-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8444161a8ff3fb63e18d350589ca33e5eb0194225a8f8366b71a1f985f841987
BLAKE2b-256 checksum
How to use checksums
f1d1d04b13f5705f53fa1fc6af4627be51fa14856cede205258df9abb83efd83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for yamldataclassconfig 2.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page