Remove Sections or Parts from YAML Files using Python

In this tutorial, you’ll learn how to remove sections or parts from YAML files using Python.

You’ll learn how to remove top-level keys, nested keys, list items, and even sections based on specific conditions.

We’ll also explore more advanced methods like using regular expressions for complex removals and handling multi-level structures.

 

 

Remove Top-Level Key

You can use the PyYAML library to load and modify YAML content.

To remove a top-level key from a YAML file, you can use the pop method:

import yaml
yaml_content = """
database:
  host: localhost
  port: 5432
  user: admin
  password: secret
logging:
  level: INFO
  file: app.log
"""
data = yaml.safe_load(yaml_content)

# Remove the 'logging' key
data.pop('logging', None)
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

database:
  host: localhost
  password: secret
  port: 5432
  user: admin

The code loads the YAML content into a dictionary, removes the logging key, and then dumps the updated content back to YAML format.

 

Remove Nested Key

To remove a nested key inside a YAML structure, access it directly and delete it using the pop method.

import yaml
yaml_content = """
application:
  name: MyApp
  version: 1.0
  settings:
    theme: light
    notifications: enabled
"""
data = yaml.safe_load(yaml_content)

# Remove the 'notifications' key inside 'settings'
data['application']['settings'].pop('notifications', None)
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

application:
  name: MyApp
  settings:
    theme: light
  version: 1.0

The code removes the notifications key from the settings section within the application key.

 

Remove Item from a List

If a YAML key contains a list, you can remove an item from that list by index or value.

import yaml
yaml_content = """
team:
  members:
    - name: Ahmed
      role: developer
    - name: Fatima
      role: designer
    - name: Omar
      role: tester
"""
data = yaml.safe_load(yaml_content)

# Remove the member with the role 'designer'
data['team']['members'] = [member for member in data['team']['members'] if member['role'] != 'designer']
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

team:
  members:
  - name: Ahmed
    role: developer
  - name: Omar
    role: tester

The code filters out the member whose role is designer from the members list.

 

Remove Section Based on a Condition

You can remove sections that meet specific conditions by iterating over the data.

import yaml
yaml_content = """
services:
  - name: webapp
    port: 8080
    enabled: true
  - name: database
    port: 3306
    enabled: false
  - name: cache
    port: 6379
    enabled: true
"""
data = yaml.safe_load(yaml_content)

# Remove services where 'enabled' is false
data['services'] = [service for service in data['services'] if service['enabled']]
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

services:
- enabled: true
  name: webapp
  port: 8080
- enabled: true
  name: cache
  port: 6379

The code removes any service where the enabled key is false.

 

Using Regular Expressions to Remove Sections

For more complex removals, you can use regular expressions with the re module.

import yaml
import re
yaml_content = """
users:
  - name: Hassan
    email: hassan@example.com
  - name: Leila
    email: leila@spam.com
  - name: Sara
    email: sara@example.com
"""

# Remove users with emails from 'spam.com'
pattern = re.compile(r'.*@spam\.com$')
data = yaml.safe_load(yaml_content)

# Filter out users matching the pattern
data['users'] = [user for user in data['users'] if not pattern.match(user['email'])]
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

users:
- email: hassan@example.com
  name: Hassan
- email: sara@example.com
  name: Sara

The code uses a regular expression to match emails ending with spam.com and removes those users.

The output excludes Leila, whose email matches the pattern.

 

Remove Multiple Keys at Once

To remove multiple keys simultaneously, you can iterate over a list of keys to delete and use the pop method to remove them:

import yaml
yaml_content = """
server:
  host: 192.168.1.1
  port: 22
  username: root
  password: rootpass
  timeout: 30
"""
data = yaml.safe_load(yaml_content)

# Keys to remove
keys_to_remove = ['username', 'password']

# Remove the specified keys
for key in keys_to_remove:
    data['server'].pop(key, None)
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

server:
  host: 192.168.1.1
  port: 22
  timeout: 30

The code removes both the username and password keys from the server section.

 

Remove Sections Between Markers

If you have sections in your YAML file delineated by specific markers, you can remove content between these markers.

yaml_content = """
settings:
  theme: dark
  language: en
# START_IGNORE
secret:
  key: 12345
  token: abcde
# END_IGNORE
features:
  enable_logging: true
"""

# Split the content into lines
lines = yaml_content.split('\n')

# Flag to indicate whether to skip lines
skip = False
new_lines = []
for line in lines:
    if '# START_IGNORE' in line:
        skip = True
        continue
    if '# END_IGNORE' in line:
        skip = False
        continue
    if not skip:
        new_lines.append(line)

# Join the lines back together
new_yaml_content = '\n'.join(new_lines)
print(new_yaml_content)

Output:

settings:
  theme: dark
  language: en
features:
  enable_logging: true

The code removes all lines between # START_IGNORE and # END_IGNORE.

 

Remove Keys Based on Their Depth

To remove keys at a certain depth in the YAML structure, you can traverse the data recursively.

import yaml
yaml_content = """
pipeline:
  steps:
    - name: build
      actions:
        - compile
        - test
    - name: deploy
      actions:
        - upload
        - notify
"""
def remove_keys_at_depth(d, depth, current_depth=0):
    if isinstance(d, dict):
        if current_depth == depth:
            return {}
        return {k: remove_keys_at_depth(v, depth, current_depth + 1) for k, v in d.items()}
    elif isinstance(d, list):
        return [remove_keys_at_depth(item, depth, current_depth) for item in d]
    else:
        return d
data = yaml.safe_load(yaml_content)

# Remove keys at depth 2
data = remove_keys_at_depth(data, depth=2)
new_yaml_content = yaml.dump(data)
print(new_yaml_content)

Output:

pipeline:
  steps:
    - {}
    - {}

The code defines a function to remove all keys at a specified depth (in this case, depth 2).

Leave a Reply

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