Convert effects to new single-file format

- dog: Convert to whole-video API with PEP 723 metadata
- identity: Add as frame-by-frame effect

Both now use @-tag docstrings for AI-readable metadata.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-12 06:52:07 +00:00
parent 89d8f4f464
commit f9d9e8c5fb
2 changed files with 55 additions and 11 deletions

View File

@@ -1,14 +1,27 @@
# /// script
# requires-python = ">=3.10"
# dependencies = ["requests"]
# ///
"""
Dog effect - returns dog.mkv regardless of input.
@effect dog
@version 1.0.0
@author @giles@artdag.rose-ash.com
@temporal true
This is a constant effect that fetches from an immutable URL.
@description
Returns dog.mkv regardless of input. This is a constant effect that
fetches from an immutable URL and verifies the content hash.
Demonstrates a whole-video effect that ignores its input.
@example
(fx dog)
"""
import hashlib
import logging
import shutil
from pathlib import Path
from typing import Any, Dict
from typing import Any, Dict, List
import requests
@@ -28,12 +41,13 @@ def file_hash(path: Path) -> str:
return hasher.hexdigest()
def effect_dog(input_path: Path, output_path: Path, config: Dict[str, Any]) -> Path:
def process(input_paths: List[Path], output_path: Path, params: Dict[str, Any], ctx) -> Path:
"""
Dog effect - ignores input, returns dog.mkv.
Whole-video API: ignores input, returns dog.mkv.
Downloads from immutable URL and verifies hash.
"""
output_path = Path(output_path)
output_path.parent.mkdir(parents=True, exist_ok=True)
# Output with correct extension
@@ -74,11 +88,6 @@ def effect_dog(input_path: Path, output_path: Path, config: Dict[str, Any]) -> P
# Copy to output
shutil.copy2(cached_file, actual_output)
logger.debug(f"EFFECT dog: {input_path.name} -> {actual_output} (input ignored)")
logger.debug(f"EFFECT dog: -> {actual_output} (input ignored)")
return actual_output
# Export for registration
effect = effect_dog
name = "dog"

35
identity/effect.py Normal file
View File

@@ -0,0 +1,35 @@
# /// script
# requires-python = ">=3.10"
# dependencies = []
# ///
"""
@effect identity
@version 1.0.0
@author @giles@artdag.rose-ash.com
@temporal false
@description
Identity effect - returns input unchanged. This is the foundational
effect where identity(x) = x. Uses frame-by-frame API but simply
passes frames through unmodified.
@example
(fx identity)
"""
import numpy as np
def process_frame(frame: np.ndarray, params: dict, state) -> tuple:
"""
Identity: return frame unchanged.
Args:
frame: RGB frame as numpy array (H, W, 3)
params: Unused
state: Passed through unchanged
Returns:
(frame, state) - both unchanged
"""
return frame, state