# YAML for Humans
Human-friendly YAML formatting for PyYAML that makes YAML more readable and intuitive.
## Features
- **Intelligent sequence formatting**: Strings on same line as dash (`- value`), objects on separate lines
- **Indented sequences**: Dashes are properly indented under their parent containers
- **Priority key ordering**: Important keys like `name`, `image`, `command` appear first in mappings
- **Multi-document support**: Handle multiple YAML documents with proper `---` separators
- **Kubernetes manifest ordering**: Automatic resource ordering following best practices
- **Valid YAML output**: All generated YAML passes standard YAML validation
- **Drop-in replacement**: Compatible with existing PyYAML code
## Quick Start
```python
from yaml_for_humans import dumps, dump
# Your data
data = {
'containers': [
{
'ports': [8080, 9090],
'name': 'web-server', # name will appear first
'image': 'nginx:latest',
'command': ['/bin/sh', '-c', 'nginx -g "daemon off;"']
}
]
}
# Generate human-friendly YAML
yaml_output = dumps(data)
print(yaml_output)
```
Output:
```yaml
containers:
-
name: web-server # Priority keys first
image: nginx:latest
command:
- /bin/sh # Strings inline with dash
- -c
- nginx -g "daemon off;"
ports:
- 8080
- 9090
```
## Comparison with Standard PyYAML
### Standard PyYAML Output
```yaml
containers:
- command:
- /bin/sh
- -c
- nginx -g "daemon off;"
image: nginx:latest
name: web-server
ports:
- 8080
- 9090
```
### YAML for Humans Output
```yaml
containers:
-
name: web-server
image: nginx:latest
command:
- /bin/sh
- -c
- nginx -g "daemon off;"
ports:
- 8080
- 9090
```
## Key Differences
1. **Indented sequences**: Dashes are indented under parent containers for better hierarchy visualization
2. **Priority key ordering**: Important keys (`apiVersion`, `kind`, `metadata`, `name`, `image`, `imagePullPolicy`, `env`, `envFrom`, `command`, `args`) appear first
3. **Smart formatting**: Complex objects use separate lines, simple strings stay inline
4. **Consistent indentation**: Maintains visual hierarchy throughout the document
## Installation
Install the core library:
```bash
uv add yaml-for-humans
```
Or install with CLI support:
```bash
uv add yaml-for-humans[cli]
```
### Development Installation
For development, install in editable mode:
```bash
# Install the package in editable mode
uv pip install -e .
# Or with CLI dependencies for development
uv pip install -e .[cli]
```
Then import and use:
```python
from yaml_for_humans import dumps, dump
```
## Command Line Interface (Optional)
The `huml` command-line utility converts YAML or JSON input to human-friendly YAML. It accepts input through stdin pipes or file processing:
```bash
# Convert JSON to human-friendly YAML
echo '{"name": "web", "ports": [80, 443]}' | huml
# Process existing YAML files
cat config.yaml | huml
# Use with kubectl
kubectl get deployment -o yaml | huml
# Process multi-document YAML (auto-detected)
cat manifests.yaml | huml
# Process JSON input (automatic detection)
echo '{"containers": [...]}' | huml
# Custom indentation
cat config.yaml | huml --indent 4
# Custom stdin timeout (default: 2000ms)
cat config.yaml | huml --timeout 100
# Use unsafe YAML loader (allows arbitrary Python objects - use with caution)
cat config-with-python-objects.yaml | huml --unsafe-inputs
# Process JSON Lines format (one JSON object per line)
cat logs.jsonl | huml
# Handle Kubernetes API responses with items arrays
kubectl get deployments -o json | huml # Automatically splits items into documents
# Process file inputs instead of stdin
huml --inputs config.yaml,deploy.json
# Process multiple files with glob patterns
huml --inputs "*.json,configs/*.yaml"
# Process all files in a directory (add trailing slash)
huml --inputs /path/to/configs/
# Mix glob patterns, directories, and explicit files
huml --inputs "*.json,/configs/,specific.yaml"
# Output to file or directory
kubectl get all -o json | huml --output ./k8s-resources/
```
### Stdin Input Handling
The CLI automatically detects input format and handles:
- **JSON objects**: Single objects or arrays
- **JSON Lines**: Multiple JSON objects, one per line
- **YAML documents**: Single or multi-document with `---` separators
- **Kubernetes API responses**: Objects with `items` arrays are split into separate documents
- **Format detection**: Automatic detection based on content analysis
### CLI Options
- `-i, --inputs TEXT`: Comma-delimited list of JSON/YAML file paths to process. Supports:
- Explicit file paths: `config.yaml,deploy.json`
- Glob patterns: `*.json,configs/*.yaml`
- Directories: `/path/to/directory/` (must end with `/`)
- Mixed combinations: `*.json,/configs/,specific.yaml`
- `-o, --output TEXT`: Output file or directory path (if ends with `/`, treated as directory)
- `--auto`: Automatically create output directories if they don't exist
- `--indent INTEGER`: Indentation level (default: 2)
- `-t, --timeout INTEGER`: Stdin timeout in milliseconds (default: 2000)
- `-u, --unsafe-inputs`: Use unsafe YAML loader (allows arbitrary Python objects, use with caution)
- `--help`: Show help message
- `--version`: Show version information
#### Input Processing Behavior
- **File Globbing**: Patterns like `*.json` and `configs/*.yaml` are expanded to match files
- **Directory Processing**: Paths ending with `/` process all valid JSON/YAML files in the directory
- **Invalid File Handling**: Files that can't be parsed or aren't JSON/YAML are skipped with warnings
- **Robust Processing**: Processing continues even if some files fail, reporting errors but not stopping
- **Format Detection**: Files are validated based on extension (`.json`, `.yaml`, `.yml`, `.jsonl`) and content analysis
## Multi-Document Support
### Basic Multi-Document Usage
```python
from yaml_for_humans import dumps_all, dump_all
documents = [
{'config': {'version': '1.0', 'features': ['auth', 'logging']}},
{'services': [{'name': 'web', 'image': 'nginx'}]},
{'metadata': {'created': '2025-01-01'}}
]
# Generate multi-document YAML
yaml_output = dumps_all(documents)
print(yaml_output)
```
Output:
```yaml
config:
version: '1.0'
features:
- auth
- logging
---
services:
-
name: web
image: nginx
---
metadata:
created: '2025-01-01'
```
### Kubernetes Manifests
```python
from yaml_for_humans import dumps_kubernetes_manifests
manifests = [
{'apiVersion': 'apps/v1', 'kind': 'Deployment', ...},
{'apiVersion': 'v1', 'kind': 'Service', ...},
{'apiVersion': 'v1', 'kind': 'ConfigMap', ...},
{'apiVersion': 'v1', 'kind': 'Namespace', ...}
]
# Automatically orders resources: Namespace, ConfigMap, Service, Deployment
ordered_yaml = dumps_kubernetes_manifests(manifests)
```
## API Reference
For detailed API documentation, see [API.md](API.md).
## Testing
Run the test suite with pytest:
```bash
uv run pytest tests/ -v
```
### Test Coverage
- **Unit tests**: Core emitter functionality, key ordering, YAML validity
- **Integration tests**: Real-world examples including Kubernetes manifests, Docker Compose files, CI/CD pipelines
- **Round-trip tests**: Ensure generated YAML can be parsed back correctly
## Examples
Run the example scripts to see the formatting in action:
```bash
uv run python examples/kubernetes_example.py
uv run python examples/docker_compose_example.py
uv run python examples/multi_document_example.py
uv run python examples/kubernetes_manifests_example.py
```
The examples demonstrate:
- Kubernetes deployments with priority key ordering
- Docker Compose files with intelligent sequence formatting
- Multi-document YAML with proper separators
- Kubernetes manifest ordering and resource prioritization
Raw data
{
"_id": null,
"home_page": null,
"name": "yaml-for-humans",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "yaml, formatting, kubernetes, devops, configuration",
"author": "Stephen D. Spencer",
"author_email": "Stephen D. Spencer <stephen@revsys.com>",
"download_url": "https://files.pythonhosted.org/packages/dd/f3/5f5f1de757e62a85f6381e3746d45cfc96244872acef56ad3e0f0a70f299/yaml_for_humans-1.0.4.tar.gz",
"platform": null,
"description": "# YAML for Humans\n\nHuman-friendly YAML formatting for PyYAML that makes YAML more readable and intuitive.\n\n## Features\n\n- **Intelligent sequence formatting**: Strings on same line as dash (`- value`), objects on separate lines\n- **Indented sequences**: Dashes are properly indented under their parent containers\n- **Priority key ordering**: Important keys like `name`, `image`, `command` appear first in mappings\n- **Multi-document support**: Handle multiple YAML documents with proper `---` separators\n- **Kubernetes manifest ordering**: Automatic resource ordering following best practices\n- **Valid YAML output**: All generated YAML passes standard YAML validation\n- **Drop-in replacement**: Compatible with existing PyYAML code\n\n## Quick Start\n\n```python\nfrom yaml_for_humans import dumps, dump\n\n# Your data\ndata = {\n 'containers': [\n {\n 'ports': [8080, 9090],\n 'name': 'web-server', # name will appear first\n 'image': 'nginx:latest',\n 'command': ['/bin/sh', '-c', 'nginx -g \"daemon off;\"']\n }\n ]\n}\n\n# Generate human-friendly YAML\nyaml_output = dumps(data)\nprint(yaml_output)\n```\n\nOutput:\n```yaml\ncontainers:\n -\n name: web-server # Priority keys first\n image: nginx:latest\n command:\n - /bin/sh # Strings inline with dash\n - -c\n - nginx -g \"daemon off;\"\n ports:\n - 8080\n - 9090\n```\n\n## Comparison with Standard PyYAML\n\n### Standard PyYAML Output\n```yaml\ncontainers:\n- command:\n - /bin/sh\n - -c\n - nginx -g \"daemon off;\"\n image: nginx:latest\n name: web-server\n ports:\n - 8080\n - 9090\n```\n\n### YAML for Humans Output\n```yaml\ncontainers:\n -\n name: web-server\n image: nginx:latest\n command:\n - /bin/sh\n - -c\n - nginx -g \"daemon off;\"\n ports:\n - 8080\n - 9090\n```\n\n## Key Differences\n\n1. **Indented sequences**: Dashes are indented under parent containers for better hierarchy visualization\n2. **Priority key ordering**: Important keys (`apiVersion`, `kind`, `metadata`, `name`, `image`, `imagePullPolicy`, `env`, `envFrom`, `command`, `args`) appear first\n3. **Smart formatting**: Complex objects use separate lines, simple strings stay inline\n4. **Consistent indentation**: Maintains visual hierarchy throughout the document\n\n## Installation\n\nInstall the core library:\n```bash\nuv add yaml-for-humans\n```\n\nOr install with CLI support:\n```bash\nuv add yaml-for-humans[cli]\n```\n\n### Development Installation\n\nFor development, install in editable mode:\n```bash\n# Install the package in editable mode\nuv pip install -e .\n\n# Or with CLI dependencies for development\nuv pip install -e .[cli]\n```\n\n\nThen import and use:\n\n```python\nfrom yaml_for_humans import dumps, dump\n```\n\n## Command Line Interface (Optional)\n\nThe `huml` command-line utility converts YAML or JSON input to human-friendly YAML. It accepts input through stdin pipes or file processing:\n\n```bash\n# Convert JSON to human-friendly YAML\necho '{\"name\": \"web\", \"ports\": [80, 443]}' | huml\n\n# Process existing YAML files\ncat config.yaml | huml\n\n# Use with kubectl\nkubectl get deployment -o yaml | huml\n\n# Process multi-document YAML (auto-detected)\ncat manifests.yaml | huml\n\n# Process JSON input (automatic detection)\necho '{\"containers\": [...]}' | huml\n\n# Custom indentation\ncat config.yaml | huml --indent 4\n\n# Custom stdin timeout (default: 2000ms)\ncat config.yaml | huml --timeout 100\n\n# Use unsafe YAML loader (allows arbitrary Python objects - use with caution)\ncat config-with-python-objects.yaml | huml --unsafe-inputs\n\n# Process JSON Lines format (one JSON object per line)\ncat logs.jsonl | huml\n\n# Handle Kubernetes API responses with items arrays\nkubectl get deployments -o json | huml # Automatically splits items into documents\n\n# Process file inputs instead of stdin\nhuml --inputs config.yaml,deploy.json\n\n# Process multiple files with glob patterns \nhuml --inputs \"*.json,configs/*.yaml\"\n\n# Process all files in a directory (add trailing slash)\nhuml --inputs /path/to/configs/\n\n# Mix glob patterns, directories, and explicit files\nhuml --inputs \"*.json,/configs/,specific.yaml\"\n\n# Output to file or directory\nkubectl get all -o json | huml --output ./k8s-resources/\n```\n\n### Stdin Input Handling\n\nThe CLI automatically detects input format and handles:\n\n- **JSON objects**: Single objects or arrays\n- **JSON Lines**: Multiple JSON objects, one per line \n- **YAML documents**: Single or multi-document with `---` separators\n- **Kubernetes API responses**: Objects with `items` arrays are split into separate documents\n- **Format detection**: Automatic detection based on content analysis\n\n### CLI Options\n\n- `-i, --inputs TEXT`: Comma-delimited list of JSON/YAML file paths to process. Supports:\n - Explicit file paths: `config.yaml,deploy.json`\n - Glob patterns: `*.json,configs/*.yaml`\n - Directories: `/path/to/directory/` (must end with `/`)\n - Mixed combinations: `*.json,/configs/,specific.yaml`\n- `-o, --output TEXT`: Output file or directory path (if ends with `/`, treated as directory)\n- `--auto`: Automatically create output directories if they don't exist\n- `--indent INTEGER`: Indentation level (default: 2)\n- `-t, --timeout INTEGER`: Stdin timeout in milliseconds (default: 2000)\n- `-u, --unsafe-inputs`: Use unsafe YAML loader (allows arbitrary Python objects, use with caution)\n- `--help`: Show help message\n- `--version`: Show version information\n\n#### Input Processing Behavior\n\n- **File Globbing**: Patterns like `*.json` and `configs/*.yaml` are expanded to match files\n- **Directory Processing**: Paths ending with `/` process all valid JSON/YAML files in the directory\n- **Invalid File Handling**: Files that can't be parsed or aren't JSON/YAML are skipped with warnings\n- **Robust Processing**: Processing continues even if some files fail, reporting errors but not stopping\n- **Format Detection**: Files are validated based on extension (`.json`, `.yaml`, `.yml`, `.jsonl`) and content analysis\n\n## Multi-Document Support\n\n### Basic Multi-Document Usage\n\n```python\nfrom yaml_for_humans import dumps_all, dump_all\n\ndocuments = [\n {'config': {'version': '1.0', 'features': ['auth', 'logging']}},\n {'services': [{'name': 'web', 'image': 'nginx'}]},\n {'metadata': {'created': '2025-01-01'}}\n]\n\n# Generate multi-document YAML\nyaml_output = dumps_all(documents)\nprint(yaml_output)\n```\n\nOutput:\n```yaml\nconfig:\n version: '1.0'\n features:\n - auth\n - logging\n\n---\nservices:\n -\n name: web\n image: nginx\n\n---\nmetadata:\n created: '2025-01-01'\n```\n\n### Kubernetes Manifests\n\n```python\nfrom yaml_for_humans import dumps_kubernetes_manifests\n\nmanifests = [\n {'apiVersion': 'apps/v1', 'kind': 'Deployment', ...},\n {'apiVersion': 'v1', 'kind': 'Service', ...},\n {'apiVersion': 'v1', 'kind': 'ConfigMap', ...},\n {'apiVersion': 'v1', 'kind': 'Namespace', ...}\n]\n\n# Automatically orders resources: Namespace, ConfigMap, Service, Deployment\nordered_yaml = dumps_kubernetes_manifests(manifests)\n```\n\n## API Reference\n\nFor detailed API documentation, see [API.md](API.md).\n\n## Testing\n\nRun the test suite with pytest:\n\n```bash\nuv run pytest tests/ -v\n```\n\n### Test Coverage\n\n- **Unit tests**: Core emitter functionality, key ordering, YAML validity\n- **Integration tests**: Real-world examples including Kubernetes manifests, Docker Compose files, CI/CD pipelines\n- **Round-trip tests**: Ensure generated YAML can be parsed back correctly\n\n## Examples\n\nRun the example scripts to see the formatting in action:\n\n```bash\nuv run python examples/kubernetes_example.py\nuv run python examples/docker_compose_example.py\nuv run python examples/multi_document_example.py\nuv run python examples/kubernetes_manifests_example.py\n```\n\nThe examples demonstrate:\n- Kubernetes deployments with priority key ordering\n- Docker Compose files with intelligent sequence formatting\n- Multi-document YAML with proper separators\n- Kubernetes manifest ordering and resource prioritization\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Human-friendly YAML formatting with intelligent sequence handling and priority key ordering",
"version": "1.0.4",
"project_urls": {
"Repository": "https://github.com/gladiatr72/yaml-for-humans"
},
"split_keywords": [
"yaml",
" formatting",
" kubernetes",
" devops",
" configuration"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f776afd4a6d2aabb734674698eb845eb241072f772f6b979aca4b77c70557b43",
"md5": "e802e9514f63e2191955442d897e1112",
"sha256": "ced3d86f3da4cbd2d9843073ac08572de23e42bd34054648fc3cfcea0a12643c"
},
"downloads": -1,
"filename": "yaml_for_humans-1.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e802e9514f63e2191955442d897e1112",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 26572,
"upload_time": "2025-09-05T20:52:37",
"upload_time_iso_8601": "2025-09-05T20:52:37.123039Z",
"url": "https://files.pythonhosted.org/packages/f7/76/afd4a6d2aabb734674698eb845eb241072f772f6b979aca4b77c70557b43/yaml_for_humans-1.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ddf35f5f1de757e62a85f6381e3746d45cfc96244872acef56ad3e0f0a70f299",
"md5": "434ef477e2dd8b6bd6e480f796e2beec",
"sha256": "0719409c13aed6d6fc9700f1315a52e742545fdfe7413d84f424044b97789cd9"
},
"downloads": -1,
"filename": "yaml_for_humans-1.0.4.tar.gz",
"has_sig": false,
"md5_digest": "434ef477e2dd8b6bd6e480f796e2beec",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 19246,
"upload_time": "2025-09-05T20:52:38",
"upload_time_iso_8601": "2025-09-05T20:52:38.082241Z",
"url": "https://files.pythonhosted.org/packages/dd/f3/5f5f1de757e62a85f6381e3746d45cfc96244872acef56ad3e0f0a70f299/yaml_for_humans-1.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-05 20:52:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "gladiatr72",
"github_project": "yaml-for-humans",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "yaml-for-humans"
}