pyya 0.1.15
Convert YAML/TOML configuration files to Python objects
Requires Python: >=3.8

# pyya - Simple tool that converts YAML/TOML configuration files to Python objects

![PyPI - Downloads](https://img.shields.io/pypi/dd/pyya)
[![ClickPy Dashboard](https://img.shields.io/badge/clickpy-dashboard-orange)](https://clickpy.clickhouse.com/dashboard/pyya)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/shadowy-pycoder/pyya/total)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyya)
[![PyPI - Link](https://img.shields.io/badge/pypi-link-blue)](https://pypi.org/project/pyya/)
![PyPI - Version](https://img.shields.io/pypi/v/pyya)
![PyPI - Wheel](https://img.shields.io/pypi/wheel/pyya)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

## Features

- Very `lightweight` and `simple` API (currently it contains only one function)
- `Easy` to use
- Based on popular and well-tested libraries (like `pydantic`, `camel-converter`, `PyYAML`, `toml` and `munch`)
- Automatically `merge` default and production configuration files
- Convert keys in configuration files to `snake_case`
- YAML/TOML validation with `Pydantic` models
- Generate stub files for your dynamic configuration with `pyya` CLI tool.

## Installation

```shell
pip install pyya
```

Or download a specific version from [Releases](https://github.com/shadowy-pycoder/pyya/releases) page and install it with:

```shell
pip install /path/to/pyya-[version]-py3-none-any.whl
```

## Usage

### Example

Create YAML configuration files for your project:

```yaml
# default.config.yaml - this file usually goes to version control system
database:
  host: localhost
  port: 5432
  username: postgres
  password: postgres

redis:
  host: localhost
  port: 6379
```

```yaml
# config.yaml - this file for production usage
database:
  username: username
  password: password
  name: db
```

Import configuration files in your Python code with `pyya`:

```python
# config.py
import json

from pyya import init_config, logger

logger.setLevel(logging.INFO)

config = init_config(
    'config.yaml', 'default.config.yaml',
    convert_keys_to_snake_case = False,
    add_underscore_prefix_to_keywords = False,
    raise_error_non_identifiers = False,
    replace_dashes_with_underscores = False,
    merge_configs = True,
    sections_ignored_on_merge = ['redis'], # do not include redis in your config
    validate_data_types = True,
    allow_extra_sections = True,
    warn_extra_sections = True,
    )
print(json.dumps(config))

# Output:
# 2025-09-05 09:13:17,280         WARNING         pyya            The following extra sections will be ignored:
# {'database.name': 'db'}
# 2025-09-05 09:13:17,281         INFO            pyya            The following sections were overwritten:
# {database: {'host': 'localhost', 'port': 5432}}
# {database: {"host": "localhost", "port": 5432, "username": "username", "password": "password"}}

```

As you can see, `pyya` automatically merges default config file with production config file.

Under the hood `pyya` uses [PyYAML](https://pypi.org/project/PyYAML/) to parse YAML files and [munch](https://pypi.org/project/munch/) library to create attribute-stylish dictionaries.

For TOML files the logic is the same except you should point `pyya` to correct TOML files (e.g. `config.toml`)

### Flags

```python
# convert `camelCase` or `PascalCase` keys to `snake_case`
convert_keys_to_snake_case=False
```

```python
# add underscore prefix to keys that are Python keywords
add_underscore_prefix_to_keywords=False
```

```python
# raise error if key name is not valid Python identifier
raise_error_non_identifiers=False
```

```python
# replace dashes with underscores in section names and keys
replace_dashes_with_underscores=False
```

```python
# merge default and production configuration files
# setting to `False` disables below flags and makes default config optional
# `False` means "open config file and apply `yaml.safe_load` and `munchify` with specified formatting"
merge_configs=True
```

```python
# list of sections to ignore when merging configs
# it is useful when you have examples in your default config but do not want to have in the main one
sections_ignored_on_merge=None
```

```python
# raise error if data types in production config are not the same as default
# validation based on data types inferred from default config
validate_data_types=True
```

```python
# raise error on any extra sections in production config
allow_extra_sections=True
```

```python
# if extra sections are allowed, warn about extra keys and values
warn_extra_sections=True
```

By default autocompletion does not work with attribute-style configurations generated by `pyya`.
However, you can generate special stub files with `.pyi` extension to make you LSP or `mypy` to properly suggest configuration fields.

With `pyya` it actually very straightforward (assuming you have `config.py` file like in the example above):

```shell
# pyya is a CLI tool installed automatically when you run pip install
pyya --input "default.config.yaml" --output "config.pyi"
```

This will create a special file with type hints for `config.py` file (note that both files should have the same basename).

## Contributing

Are you a developer?

- Fork the repository `https://github.com/shadowy-pycoder/pyya/fork`
- Clone the repository: `git clone https://github.com/<your-username>/pyya.git && cd pyya`
- Create your feature branch: `git switch -c my-new-feature`
- Commit your changes: `git commit -am 'Add some feature'`
- Push to the branch: `git push origin my-new-feature`
- Submit a pull request