Anuva Python Server API Change Breakdown
Created: 2026-05-21 13:30 UTC
Summary
This change defines the worker-facing API contract between the Anuva Web App and the Anuva Python Server described in docs/AnuvaPythonServer_SystemDescription.md.
The goal is not to expose generic CMS collections directly. The goal is to provide a dedicated /api/worker/v1 contract that matches the current Python worker lifecycle: find or claim one job, fetch a complete render package, report status and diagnostics, upload the render result, and finalize the job.
The current repo already has a partial render-job API under /api/render-jobs plus a video_generation_jobs collection. That existing surface is useful implementation context, but it does not yet cover the full worker model, atomic claim flow, signed upload flow, heartbeat reporting, or the status contract described in the Python server system document.
The PresentationConfig JSON most likely belongs in RenderJobPackage.config. In the current codebase, the closest existing source is configSnapshot.publicConfig, which already represents the renderer-facing persisted config snapshot. The implementation plan should verify whether the payload should carry that public config exactly or a thin renderer wrapper around it.
Contract Flow
flowchart TD
queued["Queued render job"] --> next["GET /api/worker/v1/jobs/next or /available"]
next --> claim["POST /jobs/{jobId}/claim"]
claim --> package["GET /jobs/{jobId}/package"]
package --> config["RenderJobPackage.config carries PresentationConfig JSON"]
package --> assets["RenderJobPackage.assets signed URLs + basenames"]
config --> worker["Python worker rewrites config to localhost URLs"]
assets --> worker
worker --> progress["PATCH /jobs/{jobId}/status + POST /workers/{workerId}/heartbeat"]
progress --> upload["POST /uploads/signed -> S3 PUT -> POST /uploads/confirm"]
upload --> complete["POST /jobs/{jobId}/complete"]
worker --> fail["POST /jobs/{jobId}/fail"]
worker --> cancel["POST /jobs/{jobId}/cancel"]
```
Current Touchpoints
docs/AnuvaPythonServer_SystemDescription.mdalready defines the recommended worker-facing contract, endpoint list, and payload shapes.- src/app/api/render-jobs/route.ts exposes a narrow renderer listing route secured by
x-renderer-secret. - src/app/api/render-jobs/[jobId]/route.ts handles partial status updates and completion, but does not implement worker claim, package fetch, heartbeat, signed upload, or diagnostics flows.
- src/collections/anuvax/index.ts defines
video_generation_jobs, whose current status model and fields are close to the worker concept but still incomplete for the described contract. - src/app/(frontend)/app/presentation/actions.ts creates render jobs and stores
configSnapshot.publicConfig, which is the strongest current fit for the futureRenderJobPackage.config. - src/lib/presentation-config/schema.ts defines
PresentationConfigPublic, the likely renderer-facing config payload. - src/lib/anuva/contracts-v1.ts defines
PresentationCompilationConfig, which is a narrower orchestration contract and likely an upstream input to the final render package rather than the final package itself.
Grouped Changes
1. Worker-facing route namespace and auth model
Explanation:
Add a dedicated /api/worker/v1 route family that reflects the Python worker contract rather than stretching the current /api/render-jobs endpoints. The worker doc expects bearer-token auth, JSON bodies, and stable operation-specific routes for job acquisition, package retrieval, status updates, heartbeat, upload finalization, completion, failure, and cancellation.
Likely affected code:
src/app/api/render-jobs/**- new
src/app/api/worker/v1/** - shared worker auth/helper code under
src/lib/**
2. Render job resource model and state semantics
Explanation:
The current video_generation_jobs collection is close but not fully aligned with the worker contract. The worker model introduces claimed and uploadFailed as first-class states, expects claim ownership fields, and treats progress as 0.0..1.0. The current collection uses queued, inProgress, uploading, completed, failed, and cancelled, with progress effectively treated as 0..100. The plan needs to decide whether storage should move to worker-native semantics or whether translation happens at the API boundary.
Likely affected code:
src/collections/anuvax/index.tssrc/payload-types.ts- job creation/update paths in
src/app/(frontend)/app/presentation/actions.ts - worker-facing route handlers
3. Atomic claim and next-job behavior
Explanation:
The Python server assumes one active job at a time and requires atomic claim semantics shared by both automatic and manual claiming. The current repo exposes a simple queued-job listing route but no dedicated claim operation. This change needs server-side claim rules, worker ownership tracking, conflict responses, and a stable next/available query shape.
Likely affected code:
- new worker routes under
src/app/api/worker/v1/jobs/** src/collections/anuvax/index.ts- possibly shared render-job service helpers under
src/lib/**
4. Render package payload and PresentationConfig placement
Explanation:
This is the core contract decision. The Python worker doc states that RenderJobPackage.config is opaque to the worker except for local rewriting and delivery to Unity. In the current codebase, the likely payload for that field is PresentationConfigPublic, because it already represents the renderer-facing config snapshot persisted at render-job creation time. PresentationCompilationConfig appears better suited as an upstream compile contract, not the final worker package.
Likely affected code:
src/app/(frontend)/app/presentation/actions.tssrc/lib/presentation-config/schema.tssrc/lib/anuva/contracts-v1.ts- new package-builder logic under
src/lib/**or worker routes
5. Asset manifest and local rewrite expectations
Explanation:
The package contract must provide signed or otherwise protected asset URLs plus safe basenames so the worker can materialize a deterministic local workspace and rewrite Unity-facing URLs to localhost. The existing render-job snapshot stores config but does not yet expose a formal asset manifest optimized for the Python worker.
Likely affected code:
- render package assembly logic
- media/presentation lookup helpers in
src/lib/** - route handlers that expose
GET /api/worker/v1/jobs/{jobId}/package
6. Status, diagnostics, heartbeat, and cancellation APIs
Explanation:
The current patch route supports basic status updates and completion. The worker contract requires more: claim ownership-aware status transitions, heartbeat ingestion, rich failure diagnostics, explicit cancellation semantics, and a cheap summary endpoint for cancellation polling. These are operational APIs, not just render-result callbacks.
Likely affected code:
- current render-job update route logic
- new worker routes for
status,fail,cancel, andworkers/{workerId}/heartbeat - collection fields or JSON fields for worker details and diagnostics
7. Upload finalization and media creation flow
Explanation:
The preferred production path is signed S3 upload followed by confirmation, returning a normalized UploadedMedia object with mediaId. The current route creates media directly on completion using external URLs. The new contract should formalize signed upload issuance, confirmation, and media finalization before the job transitions to completed.
Likely affected code:
- new worker upload routes
src/plugins/s3-storage-plugin.ts- media-asset creation helpers
- presentation final-video pointer updates
8. Docs and contract verification
Explanation:
Because this change defines a cross-system contract, docs parity and contract-focused verification matter as much as route code. The docs should explain the new worker namespace, route responsibilities, status model, config placement, and how the existing render-job internals map to the Python worker model.
Likely affected docs:
docs/AnuvaPythonServer_SystemDescription.mddocs/core/WorkersAndJobs.mddocs/core/SystemArchitecture.mddocs/core/PresentationConfig.mddocs/state/RouteMap.mddocs/state/CollectionMap.mddocs/state/CurrentImplementationMap.mddocs/state/KnownGaps.md
Likely affected tests:
- new route/contract tests close to worker routes
- integration tests around render-job creation and completion
- schema/contract validation tests for package payloads
Affected Product Surfaces
- Worker-facing backend API for external render workers
- Render job persistence and status tracking
- Presentation final-video completion flow
- Signed upload and media finalization path
- Render package assembly for Unity
- Operator visibility into render status, failure, and cancellation
Risks And Dependencies
PresentationConfigPublicmay still need a renderer-specific wrapper or normalization before it can safely becomeRenderJobPackage.config.- The current
video_generation_jobsstatus enum does not includeclaimedoruploadFailed, and its progress semantics do not match the worker doc. - Atomic claim semantics are easy to describe and easy to get wrong if implemented only with read-then-write logic.
- Moving from
x-renderer-secretto bearer-token worker auth changes operational setup and must avoid breaking existing renderer paths prematurely. - Signed asset URL generation and upload confirmation depend on the active S3-backed environment and media persistence behavior.
- Failure diagnostics and heartbeat payloads should stay flexible enough for the worker without polluting the core collection model with brittle fields.
- The current render-job flow updates
presentations.latestFinalVideodirectly on completion; introducing upload confirmation and richer job states changes that sequence.
Out Of Scope
- Python worker implementation changes outside the contract assumptions already documented in
docs/AnuvaPythonServer_SystemDescription.md - Unity runtime changes beyond consuming the packaged config and localhost-rewritten assets
- Reworking presentation generation, narrative generation, or scene-edit workflows
- Broad refactors of unrelated Payload collections or admin UI
- Legacy compatibility layers for old renderers unless specifically required during planning
Open Questions
Q1. Should /api/worker/v1 fully replace the current /api/render-jobs renderer API, or should both surfaces coexist temporarily during migration?
Answer: Yes, /api/worker/v1 should fully replace the current /api/render-jobs renderer API
Q2. Should RenderJobPackage.config be the current PresentationConfigPublic object exactly, or a renderer-specific object that wraps PresentationConfigPublic plus extra render metadata?
Answer: RenderJobPackage.config should be the current PresentationConfigPublic object exactly
Q3. Should render-job persistence store progress as 0.0..1.0 to match the worker contract, or keep 0..100 internally and translate at the API boundary?
Answer: Keep 0..100 internally and translate at the API boundary
Q4. Should worker heartbeat details and failure diagnostics live on video_generation_jobs, on a separate worker-oriented collection, or partly in both?
Answer: Separate worker-oriented collection
Q5. Is direct multipart upload required in V1 as a fallback, or should the initial implementation ship only the signed-upload flow described as preferred in the system document?
Answer: The initial implementation should ship only the preferred signed-upload flow