dotget¶
Simple, exact addressing for nested data
The foundational tool of the Depth pillar, dotget safely extracts values from nested data structures using dot notation paths.
Overview¶
dotget is the tool that started it all - a simple function to safely navigate nested dictionaries and lists without worrying about KeyErrors or IndexErrors.
Basic Usage¶
from depth.dotget import get
data = {
"user": {
"name": "Alice",
"contacts": {
"email": "alice@example.com",
"phone": "+1-555-0100"
}
}
}
# Get nested values
name = get(data, "user.name") # "Alice"
email = get(data, "user.contacts.email") # "alice@example.com"
missing = get(data, "user.contacts.fax") # None
Safe Navigation¶
Unlike direct dictionary access, dotget never raises exceptions:
# This would raise KeyError:
# value = data["user"]["settings"]["theme"]
# This returns None safely:
value = get(data, "user.settings.theme") # None
List Access¶
Navigate through lists using numeric indices:
data = {
"users": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35}
]
}
# Access by index
first_user = get(data, "users.0.name") # "Alice"
second_age = get(data, "users.1.age") # 25
# Negative indices work too
last_user = get(data, "users.-1.name") # "Charlie"
# Out of bounds returns None
missing = get(data, "users.10.name") # None
Mixed Structures¶
Navigate seamlessly through mixed dictionaries and lists:
data = {
"company": {
"departments": [
{
"name": "Engineering",
"teams": [
{"name": "Backend", "size": 5},
{"name": "Frontend", "size": 3}
]
}
]
}
}
# Deep navigation
team_size = get(data, "company.departments.0.teams.1.size") # 3
Real-World Examples¶
API Response Parsing¶
response = {
"data": {
"user": {
"id": 123,
"profile": {
"firstName": "Alice",
"lastName": "Smith"
}
}
},
"meta": {
"timestamp": "2024-01-01T12:00:00Z"
}
}
user_id = get(response, "data.user.id") # 123
full_name = f"{get(response, 'data.user.profile.firstName')} {get(response, 'data.user.profile.lastName')}"
Configuration Access¶
config = {
"database": {
"primary": {
"host": "db1.example.com",
"port": 5432
}
}
}
# Safe configuration access with defaults
db_host = get(config, "database.primary.host") or "localhost"
db_port = get(config, "database.primary.port") or 5432
db_user = get(config, "database.primary.user") or "postgres"
JSON Data Processing¶
import json
# Load JSON data
with open("data.json") as f:
data = json.load(f)
# Safely extract nested values
for i in range(100): # Don't know how many items
name = get(data, f"items.{i}.name")
if name is None:
break # No more items
print(name)
Design Philosophy¶
dotget embodies the principle of graceful degradation:
- Never raises exceptions for missing paths
- Returns None for any navigation failure
- Simple, predictable behavior
- Zero dependencies
Performance¶
dotget is optimized for simplicity and safety, not speed:
- O(n) where n is the depth of the path
- Minimal memory overhead
- No caching or memoization
For performance-critical applications with known schemas, direct dictionary access is faster.