YAML is a common format for config and data exchange. This guide shows how to read a YAML file into a Python dictionary with PyYAML, read nested keys, handle missing data and parse errors, load several documents from one file, and write a dict back to YAML using the safe APIs. For deeply nested keys after load, see nested dictionary in Python; to merge loaded config into an existing dict, see merge two dictionaries.
Tested on: Python 3.13.3; PyYAML 6.0.2; kernel 6.14.0-37-generic.
Read YAML file to dictionary in Python
The usual pattern is to open the file in text mode and pass the open file object to yaml.safe_load().
import yaml
with open("config.yaml", "r") as file:
config = yaml.safe_load(file)
print(config)
print(type(config))If config.yaml contains a mapping at the top level (see the sample file below), you get a dict-like structure. Example shape after loading:
{'database': {'host': 'localhost', 'port': 5432, 'enabled': True}}
<class 'dict'>Install PyYAML
The project on PyPI is named pyyaml. You import the module as yaml (not pyyaml).
python3 -m pip install pyyamlOn Linux you may use a virtual environment first so pip does not touch the system interpreter. After install, import yaml should work without error.
Sample YAML file
Save this as config.yaml next to your script (or pass a full path to open()):
database:
host: localhost
port: 5432
enabled: trueTop-level database becomes a nested dict in Python; host, port, and enabled are keys inside it.
Convert YAML to dict using yaml.safe_load()
yaml.safe_load(stream) parses one YAML document and constructs a Python object using only standard YAML tags—it does not construct arbitrary Python objects from YAML tags. The upstream PyYAML README recommends yaml.safe_load(stream) when you do not trust the YAML source.
import yaml
with open("config.yaml", "r") as file:
data = yaml.safe_load(file)
print(data)For untrusted input, prefer safe_load (or safe_load_all for multi-document streams) over a bare yaml.load() call without a carefully chosen Loader.
Access values from YAML dictionary
After loading, treat data like any dict: use [] for keys you know exist.
import yaml
with open("config.yaml", "r") as file:
config = yaml.safe_load(file)
print(config["database"])
print(config["database"]["host"])Read nested YAML as Python dict
Nested mappings in YAML map to nested dicts in Python. Scalars keep their natural types when PyYAML can infer them (for example integers and booleans).
import yaml
with open("config.yaml", "r") as file:
config = yaml.safe_load(file)
print(config["database"]["host"])
print(config["database"]["port"])
print(config["database"]["enabled"])Handle missing keys safely
If a key might be absent, use .get() so you do not raise KeyError.
import yaml
with open("config.yaml", "r") as file:
config = yaml.safe_load(file)
host = config.get("database", {}).get("host", "localhost")
print(host)You can combine this with explicit checks on config if the file might omit the whole database section.
Load multiple YAML documents using safe_load_all()
One file can contain several YAML documents separated by ---. Use yaml.safe_load_all(file) and consume the iterator (for example with list(...)).
Save as multi.yaml:
name: first
---
name: secondimport yaml
with open("multi.yaml", "r") as file:
documents = list(yaml.safe_load_all(file))
print(documents)Example output shape:
[{'name': 'first'}, {'name': 'second'}]For writing several documents at once, the safe API includes yaml.safe_dump_all() (see the PyYAML documentation for the exact signature and options).
Handle YAML parsing errors
Wrap file access and parsing so you can distinguish a missing file from bad YAML.
import yaml
try:
with open("config.yaml", "r") as file:
data = yaml.safe_load(file)
print(data)
except FileNotFoundError:
print("YAML file not found")
except yaml.YAMLError as error:
print("Invalid YAML:", error)yaml.YAMLError covers syntax problems in the YAML itself. You can still get a KeyError later if your code assumes keys that are not in the loaded dict.
Convert Python dict to YAML
To write a dict back to a file, use yaml.safe_dump() so the output uses the safe dumper (standard tags only). sort_keys=False keeps a predictable order that matches how you built the dict.
import yaml
data = {
"database": {
"host": "localhost",
"port": 5432,
}
}
with open("config.yaml", "w") as file:
yaml.safe_dump(data, file, sort_keys=False)PyYAML documents safe_dump() and safe_dump_all() as producing only standard YAML tags via SafeDumper.
safe_load() vs load() in PyYAML
Use yaml.safe_load() for normal configuration files and whenever the YAML might come from an untrusted or half-trusted place. It is the straightforward choice for “read this file into dict/list/scalars.” Under the hood it is equivalent to calling yaml.load() with the safe resolver path; the PyYAML docs and README steer you toward safe_load / safe_load_all when you do not trust the input.
The same tiny document with safe_load:
import yaml
from io import StringIO
text = "port: 5432\n"
data = yaml.safe_load(StringIO(text))
print(data){'port': 5432}yaml.load() still exists when you need a specific Loader, but in current PyYAML it requires an explicit Loader= argument (calling yaml.load(stream) alone raises TypeError). Picking the wrong loader for untrusted YAML can still be dangerous, which is why defaulting to safe_load() for “file to dict” keeps the story simple.
If you truly need yaml.load(), pass the loader you intend—for example Loader=yaml.SafeLoader matches the same tag subset as safe_load for this string:
import yaml
from io import StringIO
text = "port: 5432\n"
data = yaml.load(StringIO(text), Loader=yaml.SafeLoader)
print(data){'port': 5432}For day-to-day “YAML file to dict” workflows, prefer yaml.safe_load / yaml.safe_load_all and only reach for yaml.load(..., Loader=...) when you have a documented reason and you understand the loader’s behavior.
Common mistakes when converting YAML to dict
- Calling
yaml.load()on arbitrary files instead ofyaml.safe_load()when you do not control the YAML contents. - Forgetting to install PyYAML (
python3 -m pip install pyyaml) beforeimport yaml. - Writing
import pyyamlinstead ofimport yamlafter installing thepyyamlpackage. - Relying on indentation in YAML that does not match what you think—YAML is whitespace-sensitive.
- Assuming every file returns a dict: a list at the root becomes a Python
list; always checktype(data)when the format varies. - Forgetting that YAML sequences map to Python lists, so mixed trees are dicts whose values are often lists or nested dicts.
- Not catching
FileNotFoundErrorwhen the path is wrong or the file was not deployed. - Not catching
yaml.YAMLErrorwhen the file is hand-edited and may contain syntax errors.
Python YAML to dict quick reference table
| Task | Approach |
|---|---|
| Read one YAML file into Python | with open(path) as f: data = yaml.safe_load(f) |
| Safe default for config | yaml.safe_load |
| Several documents in one file | list(yaml.safe_load_all(f)) |
| Nested key with default | data.get("a", {}).get("b", default) |
| Write dict to YAML safely | yaml.safe_dump(data, f, sort_keys=False) |
| Malformed file | except yaml.YAMLError |
| Missing file | except FileNotFoundError |
Summary
You can turn a YAML file into Python data by installing PyYAML (pyyaml), opening the file in text mode, and calling yaml.safe_load(). For typical configs you work with a dict: navigate nested keys with chained [...] or .get() for optional sections. Use yaml.safe_load_all() when the file holds multiple ----separated documents, yaml.safe_dump() when you need to emit YAML from a dict, and combine FileNotFoundError with yaml.YAMLError so failures are easy to tell apart. Prefer safe_load over ad hoc yaml.load() unless you fully control the Loader and the trust boundary.

