Customize Indentation in YAML Files Using Python

This tutorial will guide you through various methods to customize indentation in YAML files using Python.

We’ll use popular Python libraries like PyYAML and ruamel.yaml to manipulate YAML files

 

 

Using ruamel.yaml

You can adjust the indentation in your YAML file using the ruamel.yaml library.

To customize indentation, you can use the yaml.indent() method:

from ruamel.yaml import YAML
yaml = YAML()
yaml.indent(mapping=4, sequence=4, offset=2)
data = {
    'name': 'Amr',
    'age': 30,
    'hobbies': ['reading', 'swimming', 'coding'],
    'address': {
        'street': 'Nile Street',
        'city': 'Cairo',
        'country': 'Egypt'
    }
}
with open('output.yaml', 'w') as file:
    yaml.dump(data, file)
print("output.yaml")

Output:

name: Amr
age: 30
hobbies:
    - reading
    - swimming
    - coding
address:
    street: Nile Street
    city: Cairo
    country: Egypt

In this example, we set the indentation to 4 spaces for both mappings and sequences, with an offset of 2 spaces.

 

Sequence custom indentation

To indent sequences by 4 spaces, for example, you can use a custom Dumper class:

import yaml
class IndentDumper(yaml.Dumper):
  def increase_indent(self, flow=False, indentless=False):
      return super(IndentDumper, self).increase_indent(flow, False)
data = {
  'fruits': ['apple', 'banana', 'orange'],
  'vegetables': ['carrot', 'broccoli', 'spinach']
}
yaml_string = yaml.dump(data, Dumper=IndentDumper, default_flow_style=False, indent=4)
print(yaml_string)

Output:

fruits:
    - apple
    - banana
    - orange
vegetables:
    - carrot
    - broccoli
    - spinach

The IndentDumper class overrides the increase_indent method to ensure that indentation is applied to sequences.

Adjust indentation for nested levels

To adjust indentation for nested levels, you can create a custom Dumper class:

import yaml
class CustomDumper(yaml.Dumper):
    def increase_indent(self, flow=False, indentless=False):
        return super(CustomDumper, self).increase_indent(flow, False)
data = {
    'level1': {
        'level2': {
            'level3': {
                'key': 'value'
            }
        }
    }
}
yaml_string = yaml.dump(data, Dumper=CustomDumper, default_flow_style=False, indent=4)
print(yaml_string)

Output:

level1:
    level2:
        level3:
            key: value

This custom Dumper class overrides the increase_indent method to ensure that all levels are indented, even for flow-style collections.

 

Convert tabs to spaces

Suppose you have a file named tabbed_file.yaml with the following content:

person:
    name: Hassan
    job:
        title: Software Engineer
        company: TechCorp
    skills:
        - Python
        - YAML
        - Git

To convert tabs to spaces in this YAML file, you can use a simple string replacement:

import yaml
with open('tabbed_file.yaml', 'r') as file:
    content = file.read()
spaces_content = content.replace('\t', '  ')  # Replace tabs with 2 spaces
data = yaml.safe_load(spaces_content)
with open('spaces_file.yaml', 'w') as file:
    yaml.dump(data, file, default_flow_style=False, indent=2)

Output:

person:
  job:
    company: TechCorp
    title: Software Engineer
  name: Hassan
  skills:
  - Python
  - YAML
  - Git

This script reads the YAML file with tab indentation, replaces tabs with spaces, and then writes the content back with consistent space indentation.

 

Fix over-indented lists

Suppose you have a file named over_indented.yaml with the following content:

shopping_list:
        - milk
        - bread
        - eggs
todo_list:
          - clean house
          - do laundry
          - buy groceries

To fix over-indented lists in this YAML file, you can use a regular expression to adjust the indentation:

import re
import yaml
with open('over_indented.yaml', 'r') as file:
  content = file.read()
fixed_content = re.sub(r'^(\s+)- ', lambda m: ' ' * (len(m.group(1)) - 2) + '- ', content, flags=re.MULTILINE)
try:
  data = yaml.safe_load(fixed_content)
  with open('fixed_lists.yaml', 'w') as file:
      yaml.dump(data, file, default_flow_style=False, indent=2)
except yaml.YAMLError as e:
  print(f"Error parsing YAML: {e}")
with open('fixed_lists.yaml', 'r') as file:
  print(file.read())

Output:

shopping_list:
- milk
- bread
- eggs
todo_list:
- clean house
- do laundry
- buy groceries

This script reads the YAML file with over-indented lists, adjusts the indentation of list items, and then writes the content back with consistent indentation.

Leave a Reply

Your email address will not be published. Required fields are marked *