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:
@@ -6,8 +6,7 @@ ARTDAG_DOMAIN=artdag.rose-ash.com
|
||||
# Default username (for actor endpoints)
|
||||
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=your-secret-here-generate-with-openssl-rand-hex-32
|
||||
|
||||
# Note: ARTDAG_L1 is no longer needed - L1 server URL is sent with each request
|
||||
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
environment:
|
||||
- REDIS_URL=redis://redis:6379/5
|
||||
- CACHE_DIR=/data/cache
|
||||
# L2_SERVER and L2_DOMAIN from .env file
|
||||
# L1_PUBLIC_URL, L2_SERVER, L2_DOMAIN from .env file
|
||||
volumes:
|
||||
- l1_cache:/data/cache
|
||||
depends_on:
|
||||
@@ -69,7 +69,7 @@ services:
|
||||
- .env
|
||||
environment:
|
||||
- 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:
|
||||
- l2_data:/data/l2
|
||||
depends_on:
|
||||
|
||||
11
server.py
11
server.py
@@ -93,6 +93,7 @@ class RecordRunRequest(BaseModel):
|
||||
"""Request to record an L1 run."""
|
||||
run_id: str
|
||||
output_name: str
|
||||
l1_server: str # URL of the L1 server that has this run
|
||||
|
||||
|
||||
class PublishCacheRequest(BaseModel):
|
||||
@@ -1034,13 +1035,14 @@ async def register_asset(req: RegisterRequest, user: User = Depends(get_required
|
||||
@app.post("/registry/record-run")
|
||||
async def record_run(req: RecordRunRequest, user: User = Depends(get_required_user)):
|
||||
"""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:
|
||||
resp = requests.get(f"{L1_SERVER}/runs/{req.run_id}")
|
||||
resp = requests.get(f"{l1_url}/runs/{req.run_id}")
|
||||
resp.raise_for_status()
|
||||
run = resp.json()
|
||||
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":
|
||||
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 = {
|
||||
"inputs": [{"content_hash": h} for h in run.get("inputs", [])],
|
||||
"recipe": run.get("recipe"),
|
||||
"l1_server": l1_url,
|
||||
"l1_run_id": req.run_id,
|
||||
"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,
|
||||
asset_type="video", # Could be smarter about this
|
||||
tags=["rendered", "l1"],
|
||||
metadata={"l1_run_id": req.run_id},
|
||||
metadata={"l1_server": l1_url, "l1_run_id": req.run_id},
|
||||
provenance=provenance
|
||||
), user.username)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user