yaml-for-humans


Nameyaml-for-humans JSON
Version 1.4.2 PyPI version JSON
download
home_pageNone
SummaryHuman-friendly YAML formatting with intelligent sequence handling and priority key ordering
upload_time2025-10-07 19:27:58
maintainerNone
docs_urlNone
authorStephen D. Spencer
requires_python>=3.8
licenseNone
keywords yaml formatting kubernetes devops configuration
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 9.73511s