embody
Structural Object Embodiment for Python - Transform skeletal templates into fully realized, type-safe objects through recursive hydration.
What is Embody?
Embody is a powerful library for templated object generation that goes beyond simple string formatting. It provides structural embodiment - the recursive hydration of nested data structures with type preservation, cycle detection, and intelligent traversal strategies.
Key Features
- 🎯 Type Preservation: Variables like
${count}preserve their types (int, bool, list, dict) instead of converting everything to strings - 🔄 Multiple Strategies: Choose between recursive visitor, compiled path, or iterative stack traversal
- 🎨 Multiple Syntaxes: Support for
${var},{var}, and[[var]]template syntaxes - 🛡️ Cycle Detection: Automatically detect and prevent circular references
- 📍 Path Addressing: Access nested data via JSON Pointer, dot notation, or tuple paths
- 🗺️ Mapping Interfaces: Uniform interfaces for attribute access, flattening, and path-based operations
- ⚡ Performance: Auto-selects optimal strategy based on template complexity
- 🔒 Type Safety: Full integration with Pydantic and other validation libraries
Installation
pip install embody
Quick Start
Basic Usage
from embody import embody
# Simple template embodiment
template = {"name": "${name}", "age": "${age}", "greeting": "Hello ${name}!"}
result = embody(template, {"name": "Alice", "age": 30})
# {'name': 'Alice', 'age': 30, 'greeting': 'Hello Alice!'}
Type Preservation
Unlike traditional templating, embody preserves types:
template = {
"count": "${num}", # Will be int, not string!
"active": "${flag}", # Will be bool
"items": "${list}", # Will be list
"message": "Count: ${num}", # Will be string (interpolation)
}
result = embody(template, {"num": 42, "flag": True, "list": [1, 2, 3]})
assert isinstance(result["count"], int) # True - type preserved!
assert isinstance(result["active"], bool) # True
assert isinstance(result["items"], list) # True
Nested Structures
Embody handles deep nesting naturally:
template = {
"user": {
"profile": {
"name": "${name}",
"settings": {"theme": "${theme}", "notifications": "${notify}"},
}
}
}
result = embody(template, {"name": "Bob", "theme": "dark", "notify": True})
Advanced Features
Context with Resolvers
from embody import Context
import datetime
ctx = Context({"now": lambda: datetime.datetime.now(), "user": "Alice"})
# Callables are invoked on access
print(ctx["now"]) # Current time
print(ctx["user"]) # 'Alice'
Mapping Interfaces
from embody.mappings import AttributeMapping, PathMapping
# Attribute access (Box pattern)
attr_map = AttributeMapping({"user": {"name": "Alice"}})
print(attr_map.user.name) # 'Alice'
# Path-based access
path_map = PathMapping({"a": {"b": {"c": 42}}})
print(path_map["a.b.c"]) # Dot notation
print(path_map["/a/b/c"]) # JSON Pointer
print(path_map[("a", "b", "c")]) # Tuple path
Path Addressing
from embody.paths import JSONPointer, resolve_path
data = {"users": [{"name": "Alice"}, {"name": "Bob"}]}
# JSON Pointer (RFC 6901)
ptr = JSONPointer("/users/0/name")
print(ptr.resolve(data)) # 'Alice'
# Convenience function
print(resolve_path(data, "users.0.name")) # 'Alice'
Traversal Strategies
from embody import Embodier
template = {"data": "${value}"}
# Recursive visitor (default, best for one-off templates)
embodier1 = Embodier(template, strategy="recursive")
# Compiled path (best for repeated embodiment)
embodier2 = Embodier(template, strategy="compiled")
# Auto-select based on template complexity
embodier3 = Embodier(template, strategy="auto")
result = embodier1({"value": 42})
Examples
Configuration Management
from embody import embody
import os
config_template = {
"database": {"host": "${db_host}", "port": "${db_port}", "name": "${db_name}"},
"api": {"base_url": "${api_url}", "timeout": "${timeout}"},
}
config = embody(
config_template,
{
"db_host": os.getenv("DB_HOST", "localhost"),
"db_port": int(os.getenv("DB_PORT", "5432")),
"db_name": "myapp",
"api_url": "https://api.example.com",
"timeout": 30,
},
)
API Response Templates
from embody import Embodier
response_template = {
"status": "success",
"data": {"user_id": "${id}", "name": "${name}", "timestamp": "${ts}"},
}
embodier = Embodier(response_template, strategy="compiled")
# Efficiently generate many responses
for user in users:
response = embodier({"id": user.id, "name": user.name, "ts": datetime.now()})
Backwards Compatibility
The original Templater API is fully preserved:
from embody.templater import Templater
template = {"hello": "{name}", "how are you": ["{verb}", 2, "{name} and {verb} again"]}
g = Templater.template_func(template=template)
result = g(name="NAME", verb="VERB")
# {'hello': 'NAME', 'how are you': ['VERB', 2, 'NAME and VERB again']}
Documentation
Contributing
Contributions are welcome! Please see our contributing guidelines.
License
Apache License 2.0 - see LICENSE file for details.
Metadata
Release files for embody 0.1.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| embody-0.1.10.tar.gz | 365.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| embody-0.1.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 411.1 kB
Release files / embody-0.1.10.tar.gz
| Download URL | embody-0.1.10.tar.gz |
|---|---|
| Size | 365.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
119d166edc6321972125678950cb56587bbe73d32e9357065ea78b9802a37cac
|
|
BLAKE2b-256 checksum How to use checksums |
5f3910aa4465872af7993444a17b865a66c3046edfc8daee6c127088e8f82e64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / embody-0.1.10-py3-none-any.whl
| Download URL | embody-0.1.10-py3-none-any.whl |
|---|---|
| Size | 45.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5d7485a05d3f392920e69ee17442f8b90f80e2e1d9321756afa858a72674f07c
|
|
BLAKE2b-256 checksum How to use checksums |
adb1a5d8e06a112a4aee71d2dc82e6a7f44e963b285fcb2dc2d16589e166af01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|