YAML Python Parsing
Parsing means turning YAML text into data a program can use. Python handles this work well through the PyYAML library. A few lines of code convert a file into dictionaries and lists, and a few more lines write data back to YAML.
Installing PyYAML
pip install pyyamlThe package name is pyyaml, while the module you import is yaml. Mixing these two names confuses many newcomers.
Reading a File
Suppose app.yaml holds this content:
app:
name: Shop
port: 8080
debug: false
tags:
- web
- storeLoad it with the safe loader:
import yaml
with open("app.yaml") as f:
config = yaml.safe_load(f)
print(config["app"]["name"])
print(config["app"]["tags"][0])The program prints Shop and web. Square brackets reach into dictionaries by key and into lists by position.
How YAML Maps to Python
| YAML | Python |
|---|---|
| Mapping | dict |
| List | list |
| String | str |
| Integer | int |
| Decimal number | float |
| true / false | True / False |
| null | None |
| Date | datetime.date |
Picturing the Conversion
app.yaml --> safe_load() --> Python dictionary
(text) (parser) {'app': {'name': 'Shop', ...}}
|
v
your program logic
Why safe_load Matters
The function yaml.load can build arbitrary Python objects from special tags, which lets a crafted file run harmful code. The function yaml.safe_load restricts the result to plain data types. Use safe_load for every file whose origin you do not fully control.
Reading from a String
text = "colors: [red, green]\ncount: 2"
data = yaml.safe_load(text)
print(data["count"])The same function accepts either an open file or a text string.
Writing YAML
The safe_dump function converts Python data back into YAML text.
settings = {"theme": "dark", "sizes": [10, 12, 14], "beta": True}
with open("out.yaml", "w") as f:
yaml.safe_dump(settings, f, sort_keys=False, default_flow_style=False)The argument sort_keys=False keeps the original key order. The argument default_flow_style=False produces the readable block layout.
theme: dark
sizes:
- 10
- 12
- 14
beta: trueHandling Errors
try:
data = yaml.safe_load("name: [unclosed")
except yaml.YAMLError as err:
print("Invalid YAML:", err)The exception message includes the line and column of the problem. Wrap loading code in a try block whenever users can supply the file.
Providing Defaults
port = config.get("app", {}).get("port", 3000)The get method returns a fallback when the key is missing. Chaining it protects against missing sections.
Other Libraries
| Library | Strength |
|---|---|
| PyYAML | Popular, simple, follows YAML 1.1 rules |
| ruamel.yaml | Keeps comments and formatting when editing files, supports YAML 1.2 |
| strictyaml | Rejects risky features and enforces a schema |
Working with Lists of Records
Many files hold a list of mappings, such as users or products. The loader returns a list of dictionaries, and a regular loop processes each record.
users = yaml.safe_load("""
- name: Asha
role: admin
- name: Ravi
role: editor
""")
for user in users:
print(user["name"], "is", user["role"])The program prints one line per user. Triple quotes let Python hold a multi-line YAML sample directly in the script, which suits tests and quick experiments.
Loading Several Documents
A file with several documents separated by three dashes needs safe_load_all. The function returns a generator, so convert it with list() when you need every document at once.
Typical Uses
- Reading application settings at startup.
- Loading test cases from data files.
- Converting YAML to JSON for another tool.
- Generating configuration files from templates.
Combining the json module with PyYAML converts formats in two lines: load with yaml.safe_load and print with json.dumps.
Checking Types After Loading
Printing the type of each value reveals how the parser interpreted the file. A port written as "8080" arrives as text, and a port written as 8080 arrives as an integer. Code that adds numbers fails on text, so verify types for important settings.
print(type(config["app"]["port"]))
print(type(config["app"]["debug"]))The output shows int and bool for the sample file. Convert values explicitly with int() when a file might contain quoted numbers.
Preserving Order
Modern Python dictionaries keep insertion order, and PyYAML loads keys in the order they appear in the file. The dump function sorts keys alphabetically unless you pass sort_keys=False, so set that argument when the order carries meaning for readers.
ruamel.yaml fits when a script must edit a file and preserve the comments written by humans. PyYAML covers plain reading well.
