Complex examples¶
Examples that use additional arguments for parsing and serialization.
Custom delimiters¶
import toons
data = {"users": [{"id": 1, "name": "A"}, {"id": 2, "name": "B"}]}
print(toons.dumps(data, delimiter="|"))
# users[2|]{id|name}:
# 1|A
# 2|B
Key folding (flatten nested keys)¶
import toons
payload = {
"user": {
"profile": {"name": "Alice", "role": "admin"},
"prefs": {"theme": "dark"},
}
}
print(toons.dumps(payload, key_folding="safe"))
# user.profile.name: Alice
# user.profile.role: admin
# user.prefs.theme: dark
Key folding with depth limit¶
import toons
payload = {
"a": {"b": {"c": {"d": 1}}}
}
print(toons.dumps(payload, key_folding="on", flatten_depth=2))
# a.b:
# c:
# d: 1
Parsing with relaxed rules¶
import toons
toon_str = """
items[2]:
- 1
- 2
"""
data = toons.loads(toon_str, strict=False)
print(data) # {'items': [1, 2]}
Expanding paths while parsing¶
import toons
toon_str = "path: ~/data/input.txt"
data = toons.loads(toon_str, expand_paths="safe")
print(data["path"])
Custom indentation for output¶
import toons
data = {"config": {"host": "localhost", "port": 5432}}
print(toons.dumps(data, indent=4))
# config:
# host: localhost
# port: 5432
# 1,Alice,alice@example.com
# 2,Bob,bob@example.com
# 3,Charlie,charlie@example.com
# Compare with JSON (146 characters, ~26 tokens)
import json
json_output = json.dumps({"users": users})
print(json_output)
# {"users":[{"id":1,"name":"Alice","email":"alice@example.com"},...]}
Data Export/Import¶
import toons
# Export database query results
def export_query_results(results, filename):
"""Export query results to TOON format."""
data = {"results": results, "count": len(results)}
with open(filename, "w") as f:
toons.dump(data, f)
# Import and process
def import_and_process(filename):
"""Import TOON data and process."""
with open(filename, "r") as f:
data = toons.load(f)
print(f"Processing {data['count']} results...")
for result in data['results']:
# Process each result
pass
# Usage
query_results = [
{"product": "Widget", "sales": 100, "revenue": 999.0},
{"product": "Gadget", "sales": 150, "revenue": 2175.0}
]
export_query_results(query_results, "sales.toon")
import_and_process("sales.toon")
LLM Prompt Context¶
import toons
# Prepare data for LLM prompt
def prepare_llm_context(user_data, transaction_history):
"""Prepare compact context for LLM."""
context = {
"user": user_data,
"recent_transactions": transaction_history[-5:] # Last 5
}
return toons.dumps(context)
user = {
"id": 123,
"name": "Alice",
"tier": "premium"
}
transactions = [
{"date": "2025-01-01", "amount": 99.99, "status": "completed"},
{"date": "2025-01-05", "amount": 149.50, "status": "completed"},
{"date": "2025-01-10", "amount": 75.00, "status": "pending"}
]
llm_context = prepare_llm_context(user, transactions)
print("LLM Context (TOON format):")
print(llm_context)
# user:
# id: 123
# name: Alice
# tier: premium
# recent_transactions[3]{date,amount,status}:
# 2025-01-01,99.99,completed
# 2025-01-05,149.5,completed
# 2025-01-10,75.0,pending
Error Handling¶
Handling Parse Errors¶
import toons
def safe_parse_toon(toon_str):
"""Parse TOON with error handling."""
try:
return toons.loads(toon_str)
except ValueError as e:
print(f"Parse error: {e}")
return None
# Valid TOON
result = safe_parse_toon("name: Alice\nage: 30")
print(result) # {'name': 'Alice', 'age': 30}
# Invalid TOON
result = safe_parse_toon("invalid: [syntax")
print(result) # None (with error message)
Strict Mode¶
By default, TOONS enforces strict compliance with the v3.0 specification. You can disable this for lenient parsing of slightly malformed data (e.g., blank lines in arrays).
import toons
# Malformed TOON (blank line in array is invalid in strict mode)
toon_str = """
items[2]:
- 1
- 2
"""
# Strict mode (default) - raises ValueError
try:
toons.loads(toon_str)
except ValueError as e:
print(f"Strict error: {e}")
# Non-strict mode - allows the blank line
data = toons.loads(toon_str, strict=False)
print(data) # {'items': [1, 2]}
Handling Serialization Errors¶
import toons
def safe_serialize(obj):
"""Serialize with error handling."""
try:
return toons.dumps(obj)
except ValueError as e:
print(f"Serialization error: {e}")
return None
# Valid object
result = safe_serialize({"name": "Alice"})
print(result) # name: Alice
# Invalid object (functions can't be serialized)
result = safe_serialize({"func": lambda x: x})
print(result) # None (with error message)
Round-Trip Verification¶
import toons
def verify_roundtrip(original_data):
"""Verify data survives serialization round-trip."""
# Serialize
toon_str = toons.dumps(original_data)
# Parse back
parsed_data = toons.loads(toon_str)
# Compare
if parsed_data == original_data:
print("✓ Round-trip successful")
return True
else:
print("✗ Round-trip failed")
print(f"Original: {original_data}")
print(f"Parsed: {parsed_data}")
return False
# Test with complex data
test_data = {
"users": [
{"name": "Alice", "age": 30, "active": True},
{"name": "Bob", "age": 25, "active": False}
],
"metadata": {
"version": "1.0",
"timestamp": "2025-01-01T00:00:00Z"
},
"tags": ["production", "verified"]
}
verify_roundtrip(test_data)
Advanced Parameters¶
Key Folding (Flattening Nested Objects)¶
Flatten nested object keys into dot-notation paths:
import toons
data = {
"config": {
"database": {
"host": "localhost",
"port": 5432
},
"api": {
"debug": True
}
}
}
# Without key folding (default)
print(toons.dumps(data))
# config:
# database:
# host: localhost
# port: 5432
# api:
# debug: true
# With key folding
print(toons.dumps(data, key_folding="safe"))
# config.database.host: localhost
# config.database.port: 5432
# config.api.debug: true
Flatten Depth (Limit Nesting Depth)¶
Control maximum nesting depth before flattening:
import toons
data = {
"app": {
"settings": {
"ui": {
"theme": "dark",
"language": "en"
}
}
}
}
# Only flatten up to depth 2
result = toons.dumps(data, key_folding="safe", flatten_depth=2)
# app.settings:
# ui:
# theme: dark
# language: en
Path Expansion¶
Expand environment variables and home directory paths (for deserialization):
import toons
import os
os.environ["DATA_DIR"] = "/var/data"
toon_str = """
paths[2]: ~/documents,$DATA_DIR
home: ~
"""
# Safe expansion (expand ~ and env vars)
data = toons.loads(toon_str, expand_paths="safe")
print(data)
# {
# 'paths': ['/home/user/documents', '/var/data'],
# 'home': '/home/user'
# }
# No expansion (default)
data = toons.loads(toon_str)
print(data)
# {
# 'paths': ['~/documents', '$DATA_DIR'],
# 'home': '~'
# }
Custom Delimiters¶
Use different delimiters for array and tabular data:
import toons
data = {"items": [1, 2, 3], "users": [{"name": "Alice", "age": 30}]}
# Tab delimiter
print(toons.dumps(data, delimiter="\t"))
# items[3 ]: 1 2 3
# users[1{name age}]:
# Alice 30
# Pipe delimiter
print(toons.dumps(data, delimiter="|"))
# items[3|]: 1|2|3
# users[1|{name|age}]:
# Alice|30
Custom Indentation¶
Control indentation levels:
import toons
data = {"nested": {"deeply": {"value": 42}}}
# 4-space indentation
print(toons.dumps(data, indent=4))
# nested:
# deeply:
# value: 42
# 1-space indentation
print(toons.dumps(data, indent=1))
# nested:
# deeply:
# value: 42
Strict Mode¶
Enforce strict TOON v3.0 compliance during parsing:
import toons
# Valid TOON but lax (blank line in array)
toon_str = """
items[2]:
- 1
- 2
"""
# Strict mode (default) - raises error
try:
data = toons.loads(toon_str)
except ValueError as e:
print(f"Strict mode error: {e}")
# Non-strict mode - allows leniency
data = toons.loads(toon_str, strict=False)
print(data) # {'items': [1, 2]}
Performance Comparison¶
import toons
import json
import time
def compare_formats(data, iterations=1000):
"""Compare TOON vs JSON performance and size."""
# JSON
json_start = time.time()
for _ in range(iterations):
json_str = json.dumps(data)
json.loads(json_str)
json_time = time.time() - json_start
json_size = len(json_str)
# TOON
toon_start = time.time()
for _ in range(iterations):
toon_str = toons.dumps(data)
toons.loads(toon_str)
toon_time = time.time() - toon_start
toon_size = len(toon_str)
print(f"JSON: {json_size} chars, {json_time:.3f}s")
print(f"TOON: {toon_size} chars, {toon_time:.3f}s")
print(f"Size reduction: {(1 - toon_size/json_size) * 100:.1f}%")
# Test with tabular data
users = [
{"name": f"User{i}", "age": 20 + i, "active": True}
for i in range(10)
]
compare_formats({"users": users})
See Also¶
- API Reference - Complete API documentation
- Data Types - Supported data types
- Development - Contributing examples