# YAML for Humans
Human-friendly YAML formatting for PyYAML that makes YAML more readable and intuitive.
## Features
- **Comment preservation**: Keeps original YAML comments (both standalone and end-of-line)
- **Empty line preservation**: Maintains empty lines from original YAML for better readability
- **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
- **High performance**: Optimized with 75% faster string processing and 67% less memory usage
- **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, load_with_formatting
# 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)
# Or load existing YAML with formatting preservation (comments + empty lines)
formatted_data = load_with_formatting('existing-config.yaml')
preserved_output = dumps(formatted_data) # Preserves comments and empty lines by default
```
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
## Comment and Formatting Preservation
YAML for Humans preserves comments and empty lines from the original YAML to maintain document structure and readability:
```python
from yaml_for_humans import load_with_formatting, dumps
# Load YAML file with comments and empty lines
yaml_content = '''# Application Configuration
app_name: web-service
version: 2.1.0
# Network Configuration
port: 8080
debug: false
# Database Settings
database:
host: localhost # Production host
port: 5432
'''
data = load_with_formatting(yaml_content)
# Preserve original formatting (default behavior)
preserved_output = dumps(data)
print("With formatting preservation:")
print(preserved_output)
# Disable preservation for compact output
compact_output = dumps(data, preserve_comments=False, preserve_empty_lines=False)
print("\nCompact output:")
print(compact_output)
```
**With formatting preservation:**
```yaml
# Application Configuration
app_name: web-service
version: 2.1.0
# Network Configuration
port: 8080
debug: false
# Database Settings
database:
host: localhost # Production host
port: 5432
```
**Compact output:**
```yaml
app_name: web-service
version: 2.1.0
port: 8080
debug: false
database:
host: localhost
port: 5432
```
This feature is especially useful for:
- **Configuration files** where comments explain complex settings
- **Kustomization files** where empty lines separate different resource types and configurations
- **Kubernetes manifests** where comments document resource purposes
- **CI/CD pipelines** where comments explain workflow stages
### Performance Options
Choose the right balance of features vs. performance:
```python
# Maximum performance (~7% overhead vs PyYAML)
output = dumps(data, preserve_comments=False, preserve_empty_lines=False)
# Balanced performance (preserve comments only)
output = dumps(data, preserve_comments=True, preserve_empty_lines=False)
# Full preservation (default, ~2x overhead vs PyYAML)
output = dumps(data) # preserves both comments and empty lines
```
## Installation
Install the core library:
```bash
uv add yaml-for-humans
```
Or install with CLI support:
```bash
uv add yaml-for-humans[cli]
```
Then import and use:
```python
from yaml_for_humans import dumps, dump, load_with_formatting
```
## 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"
# Preserve formatting (default behavior)
cat config.yaml | huml
# Disable formatting preservation for maximum performance
cat config.yaml | huml --no-preserve-comments --no-preserve-empty-lines
# 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)
- `--preserve-comments / --no-preserve-comments`: Preserve comments from original YAML (default: preserve)
- `--preserve-empty-lines / --no-preserve-empty-lines`: Preserve empty lines from original YAML (default: preserve)
- `--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)
```
## Performance
YAML for Humans is optimized for both performance and readability:
- **Basic mode**: Only ~7% overhead vs PyYAML while maintaining human-friendly formatting
- **With formatting preservation**: ~2x overhead vs PyYAML for full comment and empty line preservation
- **Recent optimizations**: 75% faster string processing, 67% less memory usage
- **Smart defaults**: Preserves formatting by default, but easily configurable for performance-critical applications
## API Reference
For detailed API documentation, see [API.md](API.md).
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/0c/8e/73f511d4b19887aa92431f96b8ec562fd8118aab220307c15c0980eabd9a/yaml_for_humans-1.4.2.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- **Comment preservation**: Keeps original YAML comments (both standalone and end-of-line)\n- **Empty line preservation**: Maintains empty lines from original YAML for better readability\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- **High performance**: Optimized with 75% faster string processing and 67% less memory usage\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, load_with_formatting\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# Or load existing YAML with formatting preservation (comments + empty lines)\nformatted_data = load_with_formatting('existing-config.yaml')\npreserved_output = dumps(formatted_data) # Preserves comments and empty lines by default\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## Comment and Formatting Preservation\n\nYAML for Humans preserves comments and empty lines from the original YAML to maintain document structure and readability:\n\n```python\nfrom yaml_for_humans import load_with_formatting, dumps\n\n# Load YAML file with comments and empty lines\nyaml_content = '''# Application Configuration\napp_name: web-service\nversion: 2.1.0\n\n# Network Configuration\nport: 8080\ndebug: false\n\n# Database Settings\ndatabase:\n host: localhost # Production host\n port: 5432\n'''\n\ndata = load_with_formatting(yaml_content)\n\n# Preserve original formatting (default behavior)\npreserved_output = dumps(data)\nprint(\"With formatting preservation:\")\nprint(preserved_output)\n\n# Disable preservation for compact output\ncompact_output = dumps(data, preserve_comments=False, preserve_empty_lines=False)\nprint(\"\\nCompact output:\")\nprint(compact_output)\n```\n\n**With formatting preservation:**\n```yaml\n# Application Configuration\napp_name: web-service\nversion: 2.1.0\n\n# Network Configuration\nport: 8080\ndebug: false\n\n# Database Settings\ndatabase:\n host: localhost # Production host\n port: 5432\n```\n\n**Compact output:**\n```yaml\napp_name: web-service\nversion: 2.1.0\nport: 8080\ndebug: false\ndatabase:\n host: localhost\n port: 5432\n```\n\nThis feature is especially useful for:\n- **Configuration files** where comments explain complex settings\n- **Kustomization files** where empty lines separate different resource types and configurations\n- **Kubernetes manifests** where comments document resource purposes\n- **CI/CD pipelines** where comments explain workflow stages\n\n### Performance Options\n\nChoose the right balance of features vs. performance:\n\n```python\n# Maximum performance (~7% overhead vs PyYAML)\noutput = dumps(data, preserve_comments=False, preserve_empty_lines=False)\n\n# Balanced performance (preserve comments only)\noutput = dumps(data, preserve_comments=True, preserve_empty_lines=False)\n\n# Full preservation (default, ~2x overhead vs PyYAML)\noutput = dumps(data) # preserves both comments and empty lines\n```\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\nThen import and use:\n\n```python\nfrom yaml_for_humans import dumps, dump, load_with_formatting\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# Preserve formatting (default behavior)\ncat config.yaml | huml\n\n# Disable formatting preservation for maximum performance\ncat config.yaml | huml --no-preserve-comments --no-preserve-empty-lines\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- `--preserve-comments / --no-preserve-comments`: Preserve comments from original YAML (default: preserve)\n- `--preserve-empty-lines / --no-preserve-empty-lines`: Preserve empty lines from original YAML (default: preserve)\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## Performance\n\nYAML for Humans is optimized for both performance and readability:\n\n- **Basic mode**: Only ~7% overhead vs PyYAML while maintaining human-friendly formatting\n- **With formatting preservation**: ~2x overhead vs PyYAML for full comment and empty line preservation\n- **Recent optimizations**: 75% faster string processing, 67% less memory usage\n- **Smart defaults**: Preserves formatting by default, but easily configurable for performance-critical applications\n\n## API Reference\n\nFor detailed API documentation, see [API.md](API.md).\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Human-friendly YAML formatting with intelligent sequence handling and priority key ordering",
"version": "1.4.2",
"project_urls": {
"Repository": "https://github.com/gladiatr72/yaml-for-humans"
},
"split_keywords": [
"yaml",
" formatting",
" kubernetes",
" devops",
" configuration"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "2ee41f1062189c003a07182f0be7c28b79c00d96335717a69c771e3378af290f",
"md5": "4372b2cd80ea68a09ae910fbc16d28c5",
"sha256": "2e04383ed248712faa0b7b89d35e817f13a54d7bf142b3ba138ac00577b76f59"
},
"downloads": -1,
"filename": "yaml_for_humans-1.4.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4372b2cd80ea68a09ae910fbc16d28c5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 38898,
"upload_time": "2025-10-07T19:27:57",
"upload_time_iso_8601": "2025-10-07T19:27:57.335765Z",
"url": "https://files.pythonhosted.org/packages/2e/e4/1f1062189c003a07182f0be7c28b79c00d96335717a69c771e3378af290f/yaml_for_humans-1.4.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0c8e73f511d4b19887aa92431f96b8ec562fd8118aab220307c15c0980eabd9a",
"md5": "02707a43d93ea629965b53fc57bcc732",
"sha256": "85779bd9b2c9cbf785ac33fcd2fe83b8816adc684a9b73b71cf1a4c4abd4d67a"
},
"downloads": -1,
"filename": "yaml_for_humans-1.4.2.tar.gz",
"has_sig": false,
"md5_digest": "02707a43d93ea629965b53fc57bcc732",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 28832,
"upload_time": "2025-10-07T19:27:58",
"upload_time_iso_8601": "2025-10-07T19:27:58.154779Z",
"url": "https://files.pythonhosted.org/packages/0c/8e/73f511d4b19887aa92431f96b8ec562fd8118aab220307c15c0980eabd9a/yaml_for_humans-1.4.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-07 19:27:58",
"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"
}