pyyaml

Read and write YAML with PyYAML in your browser: safe_load versus load, value types, updating a file and multi-document streams.

Python
import yaml

# Example Python dictionary
data = {
    'name': 'Alice',
    'age': 30,
    'languages': ['English', 'French'],
    'details': {
        'hobbies': ['Reading', 'Hiking'],
        'active': True
    }
}

# --- Write the dictionary to a YAML file ---
with open('data.yaml', 'w') as f:
    yaml.dump(data, f)

print("Data written to data.yaml")

# --- Read the YAML file back into a Python dictionary ---
with open('data.yaml', 'r') as f:
    loaded_data = yaml.safe_load(f)

print("\nData loaded from data.yaml:")
print(loaded_data)
Data written to data.yaml

Data loaded from data.yaml:
{'age': 30, 'details': {'active': True, 'hobbies': ['Reading', 'Hiking']}, 'languages': ['English', 'French'], 'name': 'Alice'}

PyYAML reads and writes YAML, the indented text format used for configuration files, CI pipelines and Kubernetes manifests. yaml.safe_load() turns YAML text into Python dicts, lists, strings and numbers, and yaml.safe_dump() turns them back into YAML. On this page it runs in your browser, so you can try it without installing anything. Run the example first, then paste any snippet below into a new cell to try it.

What the example does

The example writes a nested dictionary to data.yaml with yaml.dump(data, f). Nested dictionaries become indented blocks, and list items become lines starting with - . dump() sorts keys alphabetically by default, so age comes first. yaml.safe_load(f) rebuilds the dictionary, with 30 as an int and True as a bool.

Parse YAML text

safe_load() also accepts a string, and picks a Python type for each value from how it is written:

import yaml

text = """
server:
  host: example.com
  port: 8080
  debug: yes
release: 2024-03-15
countries: [GB, NO, "NO"]
version: 1.10
password:
"""

config = yaml.safe_load(text)
print(config)
print(config["server"]["port"] + 1)

8080 is an int, yes is True, the date is a datetime.date and the empty password is None. The unquoted NO and 1.10 become False and 1.1: see Good to know.

safe_load versus load

yaml.safe_load(text) is short for yaml.load(text, Loader=yaml.SafeLoader). It builds only standard YAML types. yaml.load() has no default loader in PyYAML 6 and raises TypeError without one. The loader decides what tags that start with !!python/ may do:

import yaml

plain = "point: !!python/tuple [1, 2]"
risky = "total: !!python/object/apply:builtins.sum [[1, 2, 3]]"

print(yaml.load(plain, Loader=yaml.FullLoader))   # builds a tuple
print(yaml.unsafe_load(risky))                     # calls sum() while loading

for text in (plain, risky):
    try:
        yaml.safe_load(text)
    except yaml.YAMLError as error:
        print("safe_load refused:", error.problem)

FullLoader adds a few Python types such as tuples, but refuses tags that create objects or call functions. yaml.unsafe_load() builds any object and calls any function a tag names, so a file from someone else could run code on your machine. Use safe_load() for any file you did not write.

Update a YAML file

Load the file, change the Python objects and write them back. sort_keys=False keeps the dictionary's order, so the new city key goes last, and allow_unicode=True writes ñ as it is instead of escaping it:

import yaml

with open("data.yaml") as f:
    data = yaml.safe_load(f)

data["age"] += 1
data["languages"].append("Español")
data["details"]["city"] = "Lyon"

with open("data.yaml", "w") as f:
    yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True)

print(open("data.yaml").read())
print(yaml.safe_dump({"word": "Español"}))   # without allow_unicode

Read several documents from one stream

A line of three dashes separates documents in one stream, as in Kubernetes manifests. safe_load() raises an error on such input, while safe_load_all() returns a generator with one item per document:

import yaml

stream = """
kind: Service
name: web
---
kind: Deployment
name: web
replicas: 3
"""

for doc in yaml.safe_load_all(stream):
    print(doc)

print(yaml.safe_dump_all([{"a": 1}, {"b": 2}]))

Getting the file

Files your code saves, like data.yaml, appear in the sidebar's Data tab. Running code and inspecting the result is free. Downloading the files requires a Premium plan.

Good to know

  • PyYAML follows YAML 1.1. Unquoted yes, No, ON and off become booleans, 0755 becomes the octal 493 and 12:30 becomes 750. Quote a value to keep it as a string.
  • Comments and blank lines are lost when you load a file, so writing it back removes them.
  • yaml.dump() writes Python-only tags such as !!python/tuple, which safe_load() refuses. safe_dump() writes a tuple as a plain list and raises RepresenterError for instances of your own classes.