feat: L1 server URL sent with publish request (many-to-many support)

- Add l1_server field to RecordRunRequest
- L2 fetches run data from the specified L1 URL instead of hardcoded config
- Store l1_server in provenance and metadata
- Remove ARTDAG_L1 config requirement from L2
- Update docker-stack.yml comments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-07 19:40:53 +00:00
parent 8159627651
commit 58a125de1a
3 changed files with 11 additions and 9 deletions

View File

@@ -6,8 +6,7 @@ ARTDAG_DOMAIN=artdag.rose-ash.com
# Default username (for actor endpoints) # Default username (for actor endpoints)
ARTDAG_USER=giles ARTDAG_USER=giles
# L1 server URL (for fetching run data)
ARTDAG_L1=https://l1.artdag.rose-ash.com
# JWT secret for token signing (generate with: openssl rand -hex 32) # JWT secret for token signing (generate with: openssl rand -hex 32)
JWT_SECRET=your-secret-here-generate-with-openssl-rand-hex-32 JWT_SECRET=your-secret-here-generate-with-openssl-rand-hex-32
# Note: ARTDAG_L1 is no longer needed - L1 server URL is sent with each request

View File

@@ -29,7 +29,7 @@ services:
environment: environment:
- REDIS_URL=redis://redis:6379/5 - REDIS_URL=redis://redis:6379/5
- CACHE_DIR=/data/cache - CACHE_DIR=/data/cache
# L2_SERVER and L2_DOMAIN from .env file # L1_PUBLIC_URL, L2_SERVER, L2_DOMAIN from .env file
volumes: volumes:
- l1_cache:/data/cache - l1_cache:/data/cache
depends_on: depends_on:
@@ -69,7 +69,7 @@ services:
- .env - .env
environment: environment:
- ARTDAG_DATA=/data/l2 - ARTDAG_DATA=/data/l2
# ARTDAG_DOMAIN, ARTDAG_USER, ARTDAG_L1, JWT_SECRET from .env file # ARTDAG_DOMAIN, ARTDAG_USER, JWT_SECRET from .env file
volumes: volumes:
- l2_data:/data/l2 - l2_data:/data/l2
depends_on: depends_on:

View File

@@ -93,6 +93,7 @@ class RecordRunRequest(BaseModel):
"""Request to record an L1 run.""" """Request to record an L1 run."""
run_id: str run_id: str
output_name: str output_name: str
l1_server: str # URL of the L1 server that has this run
class PublishCacheRequest(BaseModel): class PublishCacheRequest(BaseModel):
@@ -1034,13 +1035,14 @@ async def register_asset(req: RegisterRequest, user: User = Depends(get_required
@app.post("/registry/record-run") @app.post("/registry/record-run")
async def record_run(req: RecordRunRequest, user: User = Depends(get_required_user)): async def record_run(req: RecordRunRequest, user: User = Depends(get_required_user)):
"""Record an L1 run and register the output. Requires authentication.""" """Record an L1 run and register the output. Requires authentication."""
# Fetch run from L1 server # Fetch run from the specified L1 server
l1_url = req.l1_server.rstrip('/')
try: try:
resp = requests.get(f"{L1_SERVER}/runs/{req.run_id}") resp = requests.get(f"{l1_url}/runs/{req.run_id}")
resp.raise_for_status() resp.raise_for_status()
run = resp.json() run = resp.json()
except Exception as e: except Exception as e:
raise HTTPException(400, f"Failed to fetch run from L1: {e}") raise HTTPException(400, f"Failed to fetch run from L1 ({l1_url}): {e}")
if run.get("status") != "completed": if run.get("status") != "completed":
raise HTTPException(400, f"Run not completed: {run.get('status')}") raise HTTPException(400, f"Run not completed: {run.get('status')}")
@@ -1053,6 +1055,7 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
provenance = { provenance = {
"inputs": [{"content_hash": h} for h in run.get("inputs", [])], "inputs": [{"content_hash": h} for h in run.get("inputs", [])],
"recipe": run.get("recipe"), "recipe": run.get("recipe"),
"l1_server": l1_url,
"l1_run_id": req.run_id, "l1_run_id": req.run_id,
"rendered_at": run.get("completed_at") "rendered_at": run.get("completed_at")
} }
@@ -1063,7 +1066,7 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
content_hash=output_hash, content_hash=output_hash,
asset_type="video", # Could be smarter about this asset_type="video", # Could be smarter about this
tags=["rendered", "l1"], tags=["rendered", "l1"],
metadata={"l1_run_id": req.run_id}, metadata={"l1_server": l1_url, "l1_run_id": req.run_id},
provenance=provenance provenance=provenance
), user.username) ), user.username)