Add identity-then-dog recipe
Chains identity effect followed by dog effect on cat input. Demonstrates effect chaining: SOURCE → EFFECT → EFFECT → output Since identity(cat) = cat, the result is dog(cat) = dog video. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
101
render_dog_cat.py
Normal file
101
render_dog_cat.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Render dog(cat) - apply dog effect to cat image.
|
||||
|
||||
Records full provenance: inputs, effects, software, hardware, owner.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
# Add effect to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "artdag-effects" / "dog"))
|
||||
|
||||
from effect import effect_dog, DOG_HASH
|
||||
|
||||
|
||||
def file_hash(path: Path) -> str:
|
||||
"""Compute SHA3-256 hash of a file."""
|
||||
hasher = hashlib.sha3_256()
|
||||
actual_path = path.resolve() if path.is_symlink() else path
|
||||
with open(actual_path, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(65536), b""):
|
||||
hasher.update(chunk)
|
||||
return hasher.hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
# Registry hashes
|
||||
CAT_HASH = "33268b6e167deaf018cc538de12dbe562612b33e89a749391cef855b320a269b"
|
||||
DOG_EFFECT_HASH = "d048fe313433eb4e38f0e24194ffae91b896ca3e6eed3e50b2cc37b7be495555"
|
||||
ARTDAG_HASH = "96a5972de216aee12ec794dcad5f9360da2e676171eabf24a46dfe1ee5fee4b0"
|
||||
WORKSTATION_HASH = "964bf6e69dc4e2493f42375013caffe26404ec3cf8eb5d9bc170cd42a361523b"
|
||||
|
||||
# Input (cat)
|
||||
cat_path = Path.home() / "artdag-art" / "cat.jpg"
|
||||
output_dir = Path.home() / "artdag-art"
|
||||
output_path = output_dir / "dog-from-cat.mkv"
|
||||
|
||||
print("=== Rendering dog(cat) ===\n")
|
||||
|
||||
# Verify input
|
||||
input_hash = file_hash(cat_path)
|
||||
print(f"Input: {cat_path}")
|
||||
print(f"Input hash: {input_hash}")
|
||||
assert input_hash == CAT_HASH, f"Input hash mismatch! Expected {CAT_HASH}"
|
||||
|
||||
# Apply dog effect
|
||||
print(f"\nApplying dog effect...")
|
||||
result = effect_dog(cat_path, output_path, {})
|
||||
|
||||
# Verify output
|
||||
output_hash = file_hash(result)
|
||||
print(f"\nOutput: {result}")
|
||||
print(f"Output hash: {output_hash}")
|
||||
assert output_hash == DOG_HASH, f"Output hash mismatch! Expected {DOG_HASH}"
|
||||
|
||||
print(f"\n✓ dog(cat) = dog.mkv")
|
||||
print(f" Cat went in, dog came out!")
|
||||
|
||||
# Record provenance
|
||||
provenance = {
|
||||
"minted_at": datetime.now(timezone.utc).isoformat(),
|
||||
"minted_by": "@giles@artdag.rose-ash.com",
|
||||
"output": {
|
||||
"name": "dog-from-cat",
|
||||
"content_hash": output_hash,
|
||||
"local_path": str(result),
|
||||
"url": None, # To be filled after push
|
||||
},
|
||||
"inputs": [
|
||||
{"name": "cat", "content_hash": CAT_HASH}
|
||||
],
|
||||
"recipe": {
|
||||
"name": "dog-cat",
|
||||
"description": "Apply dog effect to cat"
|
||||
},
|
||||
"effects": [
|
||||
{"name": "effect:dog", "content_hash": DOG_EFFECT_HASH}
|
||||
],
|
||||
"infrastructure": {
|
||||
"software": {"name": "infra:artdag", "content_hash": ARTDAG_HASH},
|
||||
"hardware": {"name": "infra:giles-hp", "content_hash": WORKSTATION_HASH}
|
||||
}
|
||||
}
|
||||
|
||||
# Save provenance
|
||||
provenance_path = result.with_suffix(".provenance.json")
|
||||
with open(provenance_path, "w") as f:
|
||||
json.dump(provenance, f, indent=2)
|
||||
|
||||
print(f"\nProvenance saved: {provenance_path}")
|
||||
|
||||
return provenance
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user