Fix item visibility bugs and add effects web UI
- Fix recipe filter to allow owner=None (S-expression compiled recipes) - Fix media uploads to use category (video/image/audio) not MIME type - Fix IPFS imports to detect and store correct media type - Add Effects navigation link between Recipes and Media - Create effects list and detail templates with upload functionality - Add cache/not_found.html template (was missing) - Add type annotations to service classes - Add tests for item visibility and effects web UI (30 tests) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,10 +11,17 @@ import json
|
||||
import os
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Optional, List, Dict, Any, Tuple
|
||||
from typing import Optional, List, Dict, Any, Tuple, Union, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import redis
|
||||
from cache_manager import L1CacheManager
|
||||
from database import Database
|
||||
|
||||
from ..types import RunResult
|
||||
|
||||
|
||||
def compute_run_id(input_hashes: list, recipe: str, recipe_hash: str = None) -> str:
|
||||
def compute_run_id(input_hashes: Union[List[str], Dict[str, str]], recipe: str, recipe_hash: Optional[str] = None) -> str:
|
||||
"""
|
||||
Compute a deterministic run_id from inputs and recipe.
|
||||
|
||||
@@ -89,14 +96,14 @@ class RunService:
|
||||
Redis is only used for task_id mapping (ephemeral).
|
||||
"""
|
||||
|
||||
def __init__(self, database, redis, cache):
|
||||
def __init__(self, database: "Database", redis: "redis.Redis[bytes]", cache: "L1CacheManager") -> None:
|
||||
self.db = database
|
||||
self.redis = redis # Only for task_id mapping
|
||||
self.cache = cache
|
||||
self.task_key_prefix = "artdag:task:" # run_id -> task_id mapping only
|
||||
self.cache_dir = Path(os.environ.get("CACHE_DIR", "/tmp/artdag-cache"))
|
||||
|
||||
def _ensure_inputs_list(self, inputs) -> list:
|
||||
def _ensure_inputs_list(self, inputs: Any) -> List[str]:
|
||||
"""Ensure inputs is a list, parsing JSON string if needed."""
|
||||
if inputs is None:
|
||||
return []
|
||||
@@ -112,7 +119,7 @@ class RunService:
|
||||
return []
|
||||
return []
|
||||
|
||||
async def get_run(self, run_id: str) -> Optional[Dict[str, Any]]:
|
||||
async def get_run(self, run_id: str) -> Optional[RunResult]:
|
||||
"""Get a run by ID. Checks database first, then Celery task state."""
|
||||
# Check database for completed run
|
||||
cached = await self.db.get_run_cache(run_id)
|
||||
@@ -267,7 +274,7 @@ class RunService:
|
||||
|
||||
return None
|
||||
|
||||
async def list_runs(self, actor_id: str, offset: int = 0, limit: int = 20) -> list:
|
||||
async def list_runs(self, actor_id: str, offset: int = 0, limit: int = 20) -> List[RunResult]:
|
||||
"""List runs for a user. Returns completed and pending runs from database."""
|
||||
# Get completed runs from database
|
||||
completed_runs = await self.db.list_runs_by_actor(actor_id, offset=0, limit=limit + 50)
|
||||
@@ -297,14 +304,14 @@ class RunService:
|
||||
async def create_run(
|
||||
self,
|
||||
recipe: str,
|
||||
inputs: list,
|
||||
output_name: str = None,
|
||||
inputs: Union[List[str], Dict[str, str]],
|
||||
output_name: Optional[str] = None,
|
||||
use_dag: bool = True,
|
||||
dag_json: str = None,
|
||||
actor_id: str = None,
|
||||
l2_server: str = None,
|
||||
recipe_name: str = None,
|
||||
) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
|
||||
dag_json: Optional[str] = None,
|
||||
actor_id: Optional[str] = None,
|
||||
l2_server: Optional[str] = None,
|
||||
recipe_name: Optional[str] = None,
|
||||
) -> Tuple[Optional[RunResult], Optional[str]]:
|
||||
"""
|
||||
Create a new rendering run. Checks cache before executing.
|
||||
|
||||
@@ -604,7 +611,7 @@ class RunService:
|
||||
"""Detect media type for a file path."""
|
||||
return detect_media_type(path)
|
||||
|
||||
async def recover_pending_runs(self) -> Dict[str, int]:
|
||||
async def recover_pending_runs(self) -> Dict[str, Union[int, str]]:
|
||||
"""
|
||||
Recover pending runs after restart.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user