Anuva Python Server Requirements
Document Status: Draft for engineering implementation
Audience: Codex, Backend Engineers, Unity Engineers, DevOps
Recommended Path: docs/Anuva_Python_Server_Requirements.md
Primary Runtime: Python 3.11+
Primary OS: Windows Server / Windows Desktop
Secondary OS: macOS / Linux where practical
1. Purpose
This document defines the requirements for the Anuva Python Server, a local/VM-side orchestration service responsible for operating the Unity-based video generation worker.
The Python Server acts as the bridge between:
- Anuva Web App / Payload CMS backend
- Unity Video Generator Windows EXE or Unity Editor Play Mode
- Local render-job workspace on the machine
- Generated MP4 upload pipeline
- Health monitoring and operational dashboard
- Local Anuva Web App simulation for development and QA
The document is intended to be detailed enough for Codex to generate the first production-oriented implementation.
2. Source Requirement Summary
The initial requirements for the Python Script are:
- Should be cross-platform, with Windows as the primary target and Mac/Linux as secondary targets.
- Poll the Anuva Web App to check for render jobs.
- Accept a render job and download data/files to an appropriate folder on the Windows local machine.
- Control the entire lifecycle of the Unity EXE:
- Launch
- Monitor
- Exit
- Heartbeat
- Restart
- Upload generated MP4 video to the Anuva Web App
- Connect to Unity App during Unity Editor Play Mode testing
- Communicate with Unity EXE to get status messages using ZeroMQ-based messages between Python and Unity C#.
- Monitor Unity EXE health, system performance, and crashes without degrading game frame rates.
- Use packages such as
psutil,GPUtil, and logging packages. - Create a Windows service using NSSM.
- Example:
- Configure the NSSM service to run in the interactive user session, not Session 0, so it can interact with the Unity EXE.
- Serve HTTPS servers:
- Serve HTML files for Vuplex-based display inside Unity.
- Serve an HTML-based GUI for the Python monitoring service.
- Support Manual Render Job claiming from the Dashboard web interface.
- Support Anuva Web App simulation for complete local testing while the real Web App is still under development.
3. Anuva Product Context
Anuva is a Virtual Studio for businesses to create professional Presentation Videos without filming or video editing.
Users provide intent, business context, documents, images, and videos through the Anuva Web App. The system then generates or compiles:
- Voiceover scenes
- Captions
- Visual assignments
- Brand, Set, and Bot selections
- Scene timing
- Camera shot metadata
- Renderer-ready Presentation Config JSON
The final video is rendered by a Unity-based Video Generator running on a Windows machine or AWS Windows GPU VM.
The user never edits timelines, camera paths, or layouts directly. The Web App and compiler decide how the presentation should be structured. Unity consumes the compiled config and records the final MP4.
4. High-Level Platform Architecture
Anuva consists of two major runtime surfaces and one worker-side orchestration service.
4.1 Anuva Web App
The Web App is responsible for user-facing creation, asset management, AI generation, compilation, job creation, and result management.
Expected stack:
- Payload CMS v3 backend
- Next.js frontend
- Supabase/Postgres storage layer
- AWS S3 or compatible object storage for media
- Mastra-based AI assistant workflows
- Presentation Config compiler
- REST APIs for Unity/Python workers
The Web App owns:
- Users and workspaces
- Presentations
- Presentation scenes
- Media assets
- RAG sources and chunks
- Presentation compilations
- Video generation jobs
- Render status
- Final generated media records
4.2 Unity Video Generator
The Unity Video Generator is a Windows EXE, and may also run in Unity Editor Play Mode during development.
It is responsible for:
- Loading the Presentation Config JSON
- Loading referenced assets
- Setting up the 3D Set, Bot, Props, and Virtual Screen
- Playing voiceover audio
- Displaying images, captions, HTML, and videos
- Executing camera shots
- Capturing the output to MP4
- Reporting render status back to the Python Server
Unity is the rendering/capture runtime. It should not poll the Web App directly in the preferred V1 architecture. The Python Server handles external orchestration and communicates render commands to Unity.
4.3 Python Server
The Python Server is a persistent orchestration service running on the same machine as Unity.
It is responsible for:
- Polling Anuva Web App for queued render jobs
- Listing available render jobs for manual Dashboard claiming
- Claiming exactly one job at a time per worker instance unless configured otherwise
- Downloading config and assets
- Preparing a deterministic local job folder
- Launching or connecting to Unity
- Sending job start/config commands to Unity
- Receiving Unity status via ZeroMQ
- Monitoring Unity process health
- Restarting Unity when safe and appropriate
- Uploading the generated MP4 to the Web App
- Updating job status, progress, and errors
- Serving local HTTPS content for Unity Vuplex displays
- Serving a local monitoring GUI for operators
- Running a local Web App simulator for development and QA
5. Core Requirements Summary
The Python Server must:
- Be cross-platform in structure, with Windows as the primary supported production OS.
- Poll the Anuva Web App for queued render jobs.
- Claim a render job atomically before processing.
- Download all required job data and media files into a local job folder.
- Control the Unity EXE lifecycle:
- Launch
- Monitor
- Stop
- Heartbeat
- Restart
- Support connecting to Unity Editor Play Mode for development/testing.
- Communicate with Unity using ZeroMQ.
- Track Unity health, machine health, GPU health, crashes, and timeouts.
- Upload generated MP4 files back to the Anuva Web App.
- Run as a Windows service using NSSM.
- Be configured to run in an interactive user session, not Session 0, when controlling Unity graphics.
- Serve local HTTPS content for Vuplex-powered HTML screens inside Unity.
- Serve a local browser-based monitoring dashboard.
- Produce structured logs suitable for debugging and future observability.
- Support manual render-job discovery from the Dashboard web interface.
- Allow an operator/developer to view available Web App render jobs with brief summaries.
- Allow an operator/developer to manually claim a selected render job from the Dashboard instead of relying only on automatic polling.
- Support automatic polling and manual claiming as separate worker modes.
- Provide a local Anuva Web App simulation mode for end-to-end Python Server testing before the real Web App APIs are complete.
- Simulate all relevant Web App render job states, API responses, job packages, upload behavior, failure modes, and cancellation flows.
6. Non-Goals for V1
The Python Server must not:
- Generate voiceover scripts.
- Generate TTS audio.
- Run Mastra workflows.
- Compile Presentation Config JSON.
- Decide scene visuals.
- Modify camera shot selection.
- Edit Presentation Config semantics.
- Act as a user-facing Web App backend.
- Replace Payload CMS.
- Perform video editing after Unity capture, except optional validation or file checks.
The Python Server is an execution worker, not a creative or AI decisioning service.
7. Render Job Lifecycle
7.1 Job States
The Web App is expected to expose render jobs with states similar to:
queuedclaimedinProgressuploadingcompletedfailedcancelled
The Python Server should treat the Web App as the source of truth for job state.
7.2 Worker Lifecycle
The Python Server lifecycle should be:
- Start service.
- Load configuration.
- Validate local directories.
- Start internal HTTPS servers.
- Initialize ZeroMQ sockets.
- Optionally launch Unity or wait for Unity Editor connection.
- Register heartbeat with Web App if endpoint exists.
- Poll for jobs or wait for manual Dashboard claim, depending on configured acquisition mode.
- Claim a job.
- Download job package.
- Prepare local workspace.
- Send render command to Unity.
- Monitor progress.
- Detect completion or failure.
- Upload generated MP4.
- Mark job completed or failed.
- Clean up or archive local files based on retention policy.
- Return to polling or manual idle state.
7.3 Single-Job Constraint
V1 should process only one active render job per Python Server instance.
Parallel rendering on one machine is out of scope unless explicitly enabled later.
7.4 Automatic vs Manual Job Claiming Modes
The Python Server must support two job acquisition modes:
- Automatic Polling Mode
- The worker periodically polls the Web App.
- The worker automatically claims the next eligible queued job.
-
This is the default production mode.
-
Manual Claim Mode
- The worker lists available render jobs in the Dashboard.
- The operator/developer selects a job.
- The Python Server attempts to claim the selected job atomically.
- If claim succeeds, the normal render lifecycle begins.
- If claim fails, the Dashboard must show a clear reason.
A third combined mode is also allowed:
- Hybrid Mode
- The worker polls automatically when idle.
- The Dashboard can also manually claim jobs while the worker is idle.
- Manual claim must be blocked when another job is active, unless explicitly configured otherwise.
Manual Claim Mode is primarily intended for:
- Local development
- QA testing
- Debugging specific render jobs
- Controlled render execution on a developer machine
- Re-rendering selected jobs during Unity integration testing
The Python Server must never bypass Web App job-claim rules. Manual claiming still uses the same atomic claim endpoint as automatic polling.
8. Web App API Contract Assumptions
The exact Payload CMS endpoints may evolve. The Python Server should isolate all Web App communication in a dedicated client module.
Recommended module:
8.1 Required API Operations
The Python Server needs Web App client methods for:
get_next_queued_job(worker_id: str) -> RenderJob | None
claim_job(job_id: str, worker_id: str) -> RenderJob
get_job_package(job_id: str) -> RenderJobPackage
update_job_status(job_id: str, status: str, progress: float | None, message: str | None) -> None
send_worker_heartbeat(worker_id: str, payload: WorkerHeartbeat) -> None
upload_render_result(job_id: str, file_path: Path, metadata: dict) -> UploadedMedia
complete_job(job_id: str, result_media_id: str) -> None
fail_job(job_id: str, error_code: str, error_message: str, diagnostics: dict | None) -> None
cancel_job(job_id: str, reason: str) -> None
8.1.1 Render Job Listing API Operations
For manual claiming, the Web App client must also support:
list_available_jobs(
worker_id: str,
filters: RenderJobListFilters | None = None
) -> list[RenderJobSummary]
get_job_summary(job_id: str) -> RenderJobSummary
manual_claim_job(
job_id: str,
worker_id: str
) -> RenderJob
manual_claim_job may internally call the same API endpoint as claim_job, but should remain a separate Python method so the Dashboard flow is explicit and testable.
8.2 Expected Render Job Package
A render job package should contain:
{
"jobId": "string",
"workspaceId": "string",
"presentationId": "string",
"compilationId": "string",
"jobType": "preview | finalRender",
"priority": "standard | priority | fastest",
"config": {},
"assets": [
{
"assetId": "string",
"kind": "image | video | audio | html | other",
"url": "https://...",
"filename": "string",
"mimeType": "string",
"checksum": "optional string",
"required": true
}
],
"render": {
"resolution": "720p | 1080p | 4k",
"frameRate": 24,
"aspectRatio": "16:9",
"format": "mp4",
"watermark": false
}
}
8.3 Atomic Claim Requirement
Job claiming must be atomic on the Web App side.
The Python Server must never assume that a job returned by polling or manual listing is safe to process until a claim endpoint succeeds.
If claiming fails because another worker claimed the job, the Python Server should log the claim conflict and resume polling or return to manual idle state.
8.4 Render Job Summary Requirements
For Dashboard listing, each render job summary should include enough information for a developer/operator to confidently choose a job without opening the full Web App.
Recommended fields:
{
"jobId": "job_001",
"workspaceId": "workspace_001",
"presentationId": "presentation_001",
"presentationTitle": "Product Launch Video",
"jobType": "preview | finalRender",
"priority": "standard | priority | fastest",
"status": "queued",
"createdAt": "2026-05-14T10:00:00+05:30",
"requestedBy": {
"userId": "user_001",
"displayName": "Demo User",
"email": "demo@example.com"
},
"summary": {
"useCase": "Product Explainer",
"sceneCount": 8,
"targetDurationSec": 75,
"resolution": "1080p",
"setVariantName": "Modern Product Studio",
"botVariantName": "Neutral Professional"
},
"readiness": {
"renderReady": true,
"blockingIssues": []
}
}
The Dashboard should display:
- Job ID
- Presentation title
- Job type
- Priority
- Created/requested time
- Use case
- Scene count
- Target duration
- Resolution
- Render readiness
- Short status/issue summary
The Dashboard should not display sensitive signed URLs, raw config JSON, or private user data beyond what is necessary for development and operations.
8A. Local Anuva Web App Simulation Mode
The Anuva Web App is still under active development. To unblock Python Server and Unity integration, the Python Server project must include a local Web App simulation mode.
The simulator must behave like a lightweight stand-in for the real Anuva Web App worker API.
It should enable complete local testing of:
- Job listing
- Automatic job polling
- Manual job claiming
- Job package retrieval
- Asset download URLs
- Job status updates
- Worker heartbeat
- Render progress reporting
- Upload success
- Upload failure
- Job completion
- Job failure
- Job cancellation
- Web App unavailable behavior
- Invalid job package behavior
- Race conditions such as claim conflicts
8A.1 Simulator Modes
The simulator should support at least three usage modes:
- In-Process Fake Client
- Used by unit tests.
- No HTTP server required.
-
Implements the same Python interface as the real Web App client.
-
Local HTTP Simulation Server
- Runs as a local FastAPI server.
- Exposes endpoints shaped like the expected Web App worker API.
-
Used for integration testing and Dashboard testing.
-
Scenario-Based Test Harness
- Loads predefined render job scenarios from local JSON/YAML files.
- Allows deterministic testing of success and failure flows.
The Python Server must be able to switch between real Web App mode and simulation mode using configuration.
8A.2 Simulator Configuration
Example config:
webapp:
mode: "simulated" # real | simulated
base_url: "http://127.0.0.1:7090"
api_token_env: "ANUVA_WORKER_API_TOKEN"
simulator:
enabled: true
host: "127.0.0.1"
port: 7090
data_dir: "C:\\Anuva\\Worker\\simulator"
scenario: "happy_path_final_render"
auto_seed_jobs: true
simulate_latency_ms: 250
When webapp.mode is simulated, the Python Server should use the local simulator instead of the real Payload CMS backend.
8A.3 Simulator Data Layout
Recommended simulator data layout:
C:\Anuva\Worker\simulator
scenarios\
happy_path_final_render\
jobs.json
job_packages\
job_001.json
assets\
images\
videos\
audio\
html\
expected_uploads\
asset_download_failure\
jobs.json
job_packages\
job_002.json
claim_conflict\
jobs.json
job_packages\
job_003.json
uploads\
Each scenario should define:
- Initial jobs
- Job packages
- Asset files
- Simulated API behavior
- Upload behavior
- Expected state transitions
8A.4 Simulated Job State Machine
The simulator must support all relevant job states:
The simulator should track state transitions and reject invalid transitions unless explicitly configured to allow them for testing.
Example valid transition flow:
queued -> claimed -> inProgress -> uploading -> completed
queued -> claimed -> inProgress -> failed
queued -> cancelled
claimed -> cancelled
inProgress -> cancelled
8A.5 Simulator API Endpoints
The simulator should expose endpoints equivalent to the expected real Web App worker API.
Recommended endpoints:
GET /sim/jobs/available
POST /sim/jobs/{jobId}/claim
GET /sim/jobs/{jobId}/package
PATCH /sim/jobs/{jobId}/status
POST /sim/jobs/{jobId}/heartbeat
POST /sim/jobs/{jobId}/upload
POST /sim/jobs/{jobId}/complete
POST /sim/jobs/{jobId}/fail
POST /sim/jobs/{jobId}/cancel
GET /sim/assets/{scenario}/{path}
GET /sim/state
POST /sim/state/reset
POST /sim/state/load-scenario
The real Web App client abstraction should allow the simulator client and real client to share the same high-level interface.
8A.6 Required Simulation Scenarios
The simulator must include predefined scenarios for:
- Happy Path Preview Render
- One queued preview job.
- Valid config.
- All assets downloadable.
-
Upload succeeds.
-
Happy Path Final Render
- One queued final render job.
- Valid config.
- All assets downloadable.
-
Upload succeeds.
-
Manual Claim Flow
- Multiple available jobs.
- Dashboard lists jobs.
- Operator claims one selected job.
-
Claimed job is removed from available list.
-
Claim Conflict
- Job appears available.
- Claim endpoint rejects it as already claimed.
-
Dashboard displays claim failure.
-
Asset Download Failure
- Required asset URL returns 404 or simulated timeout.
-
Python Server fails job before Unity render starts.
-
Invalid Job Package
- Missing config or malformed config.
-
Python Server fails job with
JOB_PACKAGE_INVALIDorCONFIG_INVALID. -
Unity Render Failure
- Job package is valid.
-
Fake Unity or test harness emits
render.failed. -
Upload Failure
- Unity completes render.
- Simulated upload endpoint fails.
-
Python Server preserves output and marks upload failure/fail state.
-
Job Cancellation Before Render
-
Job is cancelled after claim but before Unity starts.
-
Job Cancellation During Render
- Simulator reports cancellation while Unity is rendering.
- Python sends
render.cancel.
-
Web App Unavailable
- Simulator can intentionally stop responding or return 503.
- Python Server retries and dashboard remains usable.
-
Worker Heartbeat Validation
- Simulator records worker heartbeats and exposes them via
/sim/state.
- Simulator records worker heartbeats and exposes them via
8A.7 Simulator Dashboard
The local Dashboard should include a simulator panel when simulation mode is enabled.
The simulator panel should allow developers to:
- View current simulator scenario
- Reset simulator state
- Load another scenario
- View simulated Web App jobs
- Force a job into a specific state
- Trigger cancellation for a job
- Trigger upload failure
- Trigger Web App unavailable mode
- View simulated API request history
This panel should only appear when simulator.enabled = true.
8A.8 Simulated Upload Behavior
In simulation mode, uploaded MP4 files should be copied to:
The simulator should create a fake uploaded media response:
{
"mediaId": "sim_media_job_001",
"url": "http://127.0.0.1:7090/sim/uploads/job_001/final.mp4",
"filename": "final.mp4",
"mimeType": "video/mp4",
"fileSizeBytes": 184000000
}
This allows the complete render lifecycle to be tested without Payload CMS or S3.
8A.9 Simulator Implementation Requirement
The simulator should be implemented as part of the Python Server project, not as a separate external dependency.
Recommended modules:
anuva_python_server/simulator/
__init__.py
app.py
state.py
scenarios.py
fake_client.py
models.py
uploads.py
The simulator must be optional and must not run in production unless explicitly enabled.
9. Presentation Config Handling
The Python Server receives a compiled Presentation Config JSON from the Web App or simulator.
It must:
- Save the original config as
presentation_config.original.json. - Save a renderer-local version as
presentation_config.local.json. - Rewrite asset URLs in the local version if Unity needs local file paths or local HTTPS URLs.
- Validate the basic shape before sending to Unity.
- Never modify semantic fields such as scene text, camera shot choice, timing intent, or visual assignment logic.
9.1 Public Config Fields Relevant to Unity
Unity expects the compiled config to include:
schemaVersionpresentationstudioscenes[]render
Each scene may include:
sceneIdindextimingvoiceover.textvoiceover.audio.urlvoiceover.audio.durationSecondsscreen.contentModescreen.captionscreen.images[]screen.videos[]directing.camera.shotexplainability
The Python Server must preserve these fields exactly.
9.2 Asset URL Rewriting
Depending on Unity implementation, assets may be passed as:
- Original signed Web App/S3 URLs
- Local file paths
- Local HTTPS URLs served by the Python Server
Preferred V1 approach:
- Download all required assets locally.
- Generate local HTTPS URLs for Unity and Vuplex where needed.
- Write a local config for Unity with local URLs.
Example rewrite:
{
"assetId": "img_123",
"url": "https://127.0.0.1:7443/jobs/job_001/assets/img_123/product.png",
"mimeType": "image/png"
}
The original cloud URL should be stored in the local job manifest for debugging.
10. Local Workspace Layout
The Python Server should create a root workspace directory.
Default Windows path:
Recommended layout:
C:\Anuva\Worker
config\
worker.yaml
secrets.env
jobs\
{jobId}\
job_manifest.json
presentation_config.original.json
presentation_config.local.json
assets\
images\
videos\
audio\
html\
other\
output\
final.mp4
thumbnail.png
logs\
python_job.log
unity_job.log
zmq_messages.jsonl
diagnostics\
system_snapshot_start.json
system_snapshot_end.json
crash_report.json
logs\
python_server.log
python_server.jsonl
cache\
assets\
temp\
certs\
simulator\
scenarios\
uploads\
10.1 Job Manifest
Each job folder must include a job_manifest.json.
Example:
{
"jobId": "job_001",
"workspaceId": "workspace_001",
"presentationId": "presentation_001",
"compilationId": "compilation_001",
"claimedAt": "2026-05-14T10:00:00+05:30",
"workerId": "unity-worker-01",
"jobType": "finalRender",
"status": "inProgress",
"localConfigPath": "presentation_config.local.json",
"outputPath": "output/final.mp4",
"assets": [
{
"assetId": "audio_001",
"remoteUrl": "https://...",
"localPath": "assets/audio/audio_001.mp3",
"localUrl": "https://127.0.0.1:7443/jobs/job_001/assets/audio/audio_001.mp3",
"checksum": "..."
}
]
}
11. Unity Lifecycle Management
11.1 Unity Run Modes
The Python Server should support two Unity modes.
11.1.1 Production EXE Mode
The Python Server launches and monitors a Unity Windows EXE.
Example config:
unity:
mode: exe
executable_path: "C:\\Anuva\\Unity\\AnuvaVideoGenerator.exe"
working_directory: "C:\\Anuva\\Unity"
launch_args:
- "-screen-fullscreen"
- "0"
- "-screen-width"
- "1920"
- "-screen-height"
- "1080"
11.1.2 Unity Editor Play Mode
The Python Server does not launch Unity. It waits for a running Unity Editor Play Mode instance to connect over ZeroMQ.
Example config:
This is used for development and integration testing.
11.2 Unity Process Control Requirements
In EXE mode, the Python Server must:
- Launch Unity if it is not running.
- Support launching Unity explicitly from the Dashboard before a manual job is claimed and run.
- Detect if Unity exits unexpectedly.
- Capture Unity stdout/stderr if available.
- Track process ID.
- Track process CPU and memory usage.
- Attempt graceful shutdown before force-killing.
- Avoid restart loops by applying retry limits and cooldowns.
11.3 Unity Launch Arguments
Unity should receive sufficient startup context via command-line args or ZeroMQ handshake.
Recommended launch args:
--anuva-worker-id unity-worker-01
--anuva-zmq-host 127.0.0.1
--anuva-zmq-command-port 5560
--anuva-zmq-status-port 5561
--anuva-local-server https://127.0.0.1:7443
--anuva-mode worker
The exact argument names can be adjusted, but they must be documented and stable.
11.4 Unity Readiness
After launch, the Python Server must wait for a Unity readiness message before sending a render job.
Expected Unity message:
{
"type": "unity.ready",
"unityInstanceId": "unity-abc123",
"appVersion": "0.1.0",
"protocolVersion": "1.0",
"capabilities": {
"renderMp4": true,
"previewRender": true,
"htmlScreen": true,
"videoScreen": true
}
}
If Unity does not become ready within unity_startup_timeout_sec, the Python Server must fail startup or restart Unity based on config.
11.5 Unity Restart Policy
Unity should be restarted when:
- The process exits unexpectedly.
- Heartbeat is lost for longer than configured timeout.
- Unity reports fatal internal error.
- Unity becomes unresponsive during idle state.
- A render fails due to Unity crash.
Unity should not be restarted mid-render unless:
- The render has exceeded timeout.
- Unity heartbeat is lost.
- Unity process has exited.
- Operator explicitly cancels/restarts.
12. ZeroMQ Communication
12.1 Transport
Use ZeroMQ for local communication between Python and Unity C#.
Recommended Python package:
Recommended patterns:
- Python sends commands to Unity.
- Unity sends status/events back to Python.
Possible socket arrangement:
Command channel:
Python PUSH or REQ -> Unity PULL or REP
Status channel:
Unity PUSH or PUB -> Python PULL or SUB
V1 can use REQ/REP for commands and PUSH/PULL for events.
12.2 Ports
Default local ports:
All ports must be configurable.
12.3 Message Envelope
Every ZeroMQ message must be JSON UTF-8.
Common envelope:
{
"id": "msg_001",
"type": "render.start",
"jobId": "job_001",
"timestamp": "2026-05-14T10:00:00+05:30",
"payload": {}
}
Required envelope fields:
idtypetimestamppayload
Recommended optional fields:
jobIdworkerIdunityInstanceIdcorrelationIdprotocolVersion
12.4 Python to Unity Commands
render.start
Sent when Python wants Unity to start rendering a job.
{
"id": "msg_100",
"type": "render.start",
"jobId": "job_001",
"timestamp": "2026-05-14T10:00:00+05:30",
"payload": {
"configPath": "C:\\Anuva\\Worker\\jobs\\job_001\\presentation_config.local.json",
"configUrl": "https://127.0.0.1:7443/jobs/job_001/presentation_config.local.json",
"outputPath": "C:\\Anuva\\Worker\\jobs\\job_001\\output\\final.mp4",
"jobType": "finalRender",
"render": {
"resolution": "1080p",
"frameRate": 30,
"format": "mp4"
}
}
}
render.cancel
{
"id": "msg_101",
"type": "render.cancel",
"jobId": "job_001",
"timestamp": "2026-05-14T10:01:00+05:30",
"payload": {
"reason": "cancelled_by_webapp"
}
}
unity.shutdown
{
"id": "msg_102",
"type": "unity.shutdown",
"timestamp": "2026-05-14T10:02:00+05:30",
"payload": {
"reason": "service_stopping"
}
}
unity.ping
12.5 Unity to Python Events
unity.ready
{
"id": "evt_001",
"type": "unity.ready",
"timestamp": "2026-05-14T10:00:05+05:30",
"payload": {
"unityInstanceId": "unity-abc123",
"appVersion": "0.1.0",
"protocolVersion": "1.0"
}
}
render.accepted
{
"id": "evt_002",
"type": "render.accepted",
"jobId": "job_001",
"timestamp": "2026-05-14T10:00:10+05:30",
"payload": {
"unityJobId": "unity-job-001"
}
}
render.progress
{
"id": "evt_003",
"type": "render.progress",
"jobId": "job_001",
"timestamp": "2026-05-14T10:01:10+05:30",
"payload": {
"progress": 42.5,
"phase": "capturing",
"message": "Rendering scene 4 of 10"
}
}
render.completed
{
"id": "evt_004",
"type": "render.completed",
"jobId": "job_001",
"timestamp": "2026-05-14T10:05:00+05:30",
"payload": {
"outputPath": "C:\\Anuva\\Worker\\jobs\\job_001\\output\\final.mp4",
"durationSec": 72.4,
"frameCount": 2172,
"fileSizeBytes": 184000000
}
}
render.failed
{
"id": "evt_005",
"type": "render.failed",
"jobId": "job_001",
"timestamp": "2026-05-14T10:03:00+05:30",
"payload": {
"errorCode": "UNITY_RENDER_EXCEPTION",
"errorMessage": "AVPro capture failed",
"details": {
"sceneId": "scene_004"
}
}
}
unity.heartbeat
{
"id": "evt_006",
"type": "unity.heartbeat",
"timestamp": "2026-05-14T10:03:10+05:30",
"payload": {
"state": "idle | rendering | error",
"fps": 60,
"currentJobId": "job_001"
}
}
12.6 Message Logging
All ZeroMQ messages should be logged to:
Each line should contain:
This is critical for integration debugging.
13. Asset Downloading
13.1 Download Requirements
For each job, the Python Server must download:
- Presentation Config JSON if supplied as URL
- Voiceover audio files
- Images
- Videos
- HTML/JS/CSS files for virtual screen display if required
- Any additional renderer-required files
Downloads must support:
- HTTPS
- Redirects
- Signed URLs
- Retry with backoff
- Checksum validation if checksum is provided
- MIME/type validation where practical
- File size logging
13.2 Download Failure Handling
If a required asset fails to download:
- Mark the job as failed.
- Report error code:
ASSET_DOWNLOAD_FAILED- Include:
- Asset ID
- URL host, not full signed URL in normal logs
- HTTP status
- Retry count
- Exception message
- Do not send the job to Unity.
If an optional asset fails to download, behavior should be configurable:
13.3 Asset Cache
The Python Server may maintain a content-addressed asset cache.
Cache key priority:
- Checksum
- Asset ID + updatedAt
- URL hash
Example:
V1 can implement direct per-job downloads first and add cache later.
14. Local HTTPS File Server
The Python Server must run a local HTTPS server to serve job assets and HTML content to Unity/Vuplex.
14.1 Purpose
The local HTTPS server is required for:
- Vuplex browser displays inside Unity
- HTML-based Virtual Screen content
- Local access to downloaded media via stable URLs
- Monitoring GUI
14.2 Server Requirements
The server must:
- Bind to
127.0.0.1by default. - Use HTTPS.
- Support configurable port.
- Serve static files from job folders.
- Prevent directory traversal.
- Prevent access outside the configured worker root.
- Emit access logs.
- Support large video/audio file streaming where needed.
- Set correct content types.
Default content port:
14.3 URL Structure
Recommended URL structure:
https://127.0.0.1:7443/jobs/{jobId}/presentation_config.local.json
https://127.0.0.1:7443/jobs/{jobId}/assets/images/{file}
https://127.0.0.1:7443/jobs/{jobId}/assets/videos/{file}
https://127.0.0.1:7443/jobs/{jobId}/assets/audio/{file}
https://127.0.0.1:7443/jobs/{jobId}/html/{file}
14.4 TLS Certificate
V1 can use a self-signed local certificate.
Certificate files:
The system should provide a documented helper command to generate dev certificates.
Example CLI:
15. Monitoring GUI Server
The Python Server must expose a local monitoring dashboard.
Default port:
15.1 Dashboard Purpose
The dashboard is for operators and developers.
It should show:
- Worker ID
- Current state
- Unity process state
- Unity connection state
- Current job
- Job progress
- Recent jobs
- Available Web App render jobs
- CPU usage
- RAM usage
- GPU usage
- GPU memory
- Disk free space
- Last heartbeat time
- Last error
- Log tail
- ZeroMQ connection state
- Web App connectivity state
- Simulator state when simulation mode is enabled
15.2 Dashboard Actions
V1 dashboard may support:
- View status
- View logs
- View available render jobs
- Refresh available render jobs
- View brief render job summary
- Launch Unity before manual EXE-mode job claiming/running
- Manually claim selected render job
- Restart Unity
- Stop Unity
- Retry current job if safe
- Mark current job failed if stuck
- Open local job folder
- Reset simulator state when simulator is enabled
- Load simulator scenario when simulator is enabled
Actions that mutate state should be protected with a local admin token.
The Dashboard Unity panel must display the configured unity.mode. EXE-only controls such as Launch Unity, Restart, and Stop should be visible only when unity.mode is exe; editor mode should hide those process-control actions.
15.3 Dashboard API Endpoints
Recommended internal endpoints:
GET /api/status
GET /api/jobs/current
GET /api/jobs/recent
GET /api/webapp/jobs/available
GET /api/webapp/jobs/{jobId}/summary
POST /api/webapp/jobs/{jobId}/claim
GET /api/system
GET /api/logs/tail
POST /api/unity/launch
POST /api/unity/restart
POST /api/unity/stop
POST /api/job/fail-current
GET /api/simulator/state
POST /api/simulator/reset
POST /api/simulator/load-scenario
16. System and Unity Health Monitoring
16.1 Required Packages
Recommended packages:
psutil
GPUtil
pyzmq
httpx
pydantic
pydantic-settings
fastapi
uvicorn
python-dotenv
tenacity
structlog
Optional:
16.2 Metrics to Capture
The Python Server must capture:
System
- CPU usage %
- RAM total/used/free
- Disk total/used/free for worker root
- Network connectivity to Web App
- OS name/version
- Machine hostname
- Local time
Unity Process
- Process ID
- Running/not running
- CPU usage %
- Memory usage
- Runtime duration
- Exit code
- Thread count if available
- Last stdout/stderr lines if captured
GPU
Using GPUtil where available:
- GPU name
- GPU load %
- GPU memory total
- GPU memory used
- GPU temperature
- Driver visibility if available
If GPU metrics are unavailable, the server should continue running and mark GPU metrics as unavailable.
16.3 Health Snapshot
The server should produce a health snapshot object:
{
"workerId": "unity-worker-01",
"timestamp": "2026-05-14T10:00:00+05:30",
"state": "idle",
"unity": {
"mode": "exe",
"running": true,
"pid": 1234,
"connected": true,
"lastHeartbeatAt": "2026-05-14T10:00:00+05:30"
},
"system": {
"cpuPercent": 32.5,
"memoryPercent": 64.1,
"diskFreeGb": 120.4
},
"gpu": {
"available": true,
"loadPercent": 74.2,
"memoryUsedMb": 6144,
"memoryTotalMb": 16384,
"temperatureC": 72
},
"currentJob": {
"jobId": "job_001",
"status": "rendering",
"progress": 42.5
}
}
16.4 Non-Degradation Requirement
Monitoring must not degrade Unity render frame rate.
Guidelines:
- Do not poll expensive metrics too frequently.
- Default health poll interval: 5 seconds.
- GPU poll interval: 5–10 seconds.
- Log aggregation should be asynchronous.
- Avoid heavy file scanning during render.
- Avoid synchronous HTTP calls on the render status event loop.
17. Error Handling and Failure Modes
17.1 Standard Error Codes
Use stable error codes.
Recommended codes:
WEBAPP_UNAVAILABLE
JOB_CLAIM_FAILED
JOB_CLAIM_CONFLICT
JOB_PACKAGE_INVALID
ASSET_DOWNLOAD_FAILED
CONFIG_INVALID
UNITY_NOT_READY
UNITY_START_TIMEOUT
UNITY_PROCESS_EXITED
UNITY_HEARTBEAT_TIMEOUT
UNITY_RENDER_FAILED
UNITY_RENDER_TIMEOUT
OUTPUT_FILE_MISSING
OUTPUT_FILE_INVALID
UPLOAD_FAILED
JOB_CANCELLED
SIMULATOR_SCENARIO_INVALID
INTERNAL_ERROR
17.2 Failure Report
When failing a job, send a structured payload:
{
"errorCode": "UNITY_RENDER_FAILED",
"errorMessage": "Unity reported AVPro capture failure",
"diagnostics": {
"workerId": "unity-worker-01",
"unityPid": 1234,
"jobId": "job_001",
"lastUnityEvent": {},
"systemSnapshot": {},
"logPaths": [
"jobs/job_001/logs/python_job.log",
"jobs/job_001/logs/unity_job.log"
]
}
}
Avoid uploading secrets, signed URLs, or local machine credentials in diagnostics.
17.3 Retry Policy
Polling Web App
- Retry indefinitely.
- Use exponential backoff with max interval.
- Continue local dashboard availability.
Downloading Assets
- Retry 3 times by default.
- Use exponential backoff.
- Fail job if required asset still fails.
Uploading MP4
- Retry 3–5 times.
- If upload fails after Unity render succeeded, keep output file and mark job as
failedoruploadFaileddepending on Web App support. - Provide a manual retry option.
Unity Render
- Do not blindly retry renders in V1 unless configured.
- If retry is enabled:
- Restart Unity before retry.
- Retry at most once.
- Preserve the first failure logs.
18. Upload Flow
18.1 Output Validation
Before upload, validate:
- Output file exists.
- Output file extension is
.mp4. - File size > minimum configured threshold.
- Modified time is after render start time.
- Optional duration check if ffprobe is available.
Recommended config:
18.2 Upload Metadata
Upload final MP4 with metadata:
{
"jobId": "job_001",
"workspaceId": "workspace_001",
"presentationId": "presentation_001",
"compilationId": "compilation_001",
"workerId": "unity-worker-01",
"jobType": "finalRender",
"filename": "presentation_001_final.mp4",
"mimeType": "video/mp4",
"fileSizeBytes": 184000000,
"durationSec": 72.4,
"renderStartedAt": "2026-05-14T10:00:00+05:30",
"renderCompletedAt": "2026-05-14T10:05:00+05:30"
}
18.3 Upload Destination
Preferred backend behavior:
- Python uploads to a Payload CMS endpoint.
- Payload creates a
media_assetsrecord. - Payload links the uploaded media to
video_generation_jobs.resultMedia. - Payload updates the related presentation’s
latestPreviewVideoorlatestFinalVideo.
Alternative:
- Web App issues a pre-signed upload URL.
- Python uploads directly to S3.
- Python calls a completion endpoint with object metadata.
The Python client should be designed so either strategy can be implemented.
19. Cancellation Handling
The Python Server should periodically check whether the current job has been cancelled in the Web App or simulator.
Cancellation behavior:
- If job is queued locally but not sent to Unity:
- Stop processing.
- Mark local status cancelled.
- If Unity is rendering:
- Send
render.cancelto Unity. - Wait for cancellation acknowledgement.
- If Unity does not respond, terminate Unity based on config.
- Clean up incomplete outputs.
- Notify Web App or simulator.
20. Configuration
20.1 Config File
Default config path:
Example:
worker:
id: "unity-worker-01"
display_name: "Unity Worker 01"
environment: "dev"
root_dir: "C:\\Anuva\\Worker"
poll_interval_sec: 10
max_active_jobs: 1
jobs:
acquisition_mode: "auto" # auto | manual | hybrid
list_available_limit: 25
allow_manual_claim_when_busy: false
webapp:
mode: "real" # real | simulated
base_url: "https://anuva.example.com"
api_token_env: "ANUVA_WORKER_API_TOKEN"
timeout_sec: 30
simulator:
enabled: false
host: "127.0.0.1"
port: 7090
data_dir: "C:\\Anuva\\Worker\\simulator"
scenario: "happy_path_final_render"
auto_seed_jobs: true
simulate_latency_ms: 250
unity:
mode: "exe"
executable_path: "C:\\Anuva\\Unity\\AnuvaVideoGenerator.exe"
working_directory: "C:\\Anuva\\Unity"
startup_timeout_sec: 120
heartbeat_timeout_sec: 30
render_timeout_sec: 1800
graceful_shutdown_timeout_sec: 15
restart:
enabled: true
max_attempts: 3
cooldown_sec: 20
zmq:
host: "127.0.0.1"
command_port: 5560
status_port: 5561
heartbeat_port: 5562
receive_timeout_ms: 1000
servers:
content:
enabled: true
host: "127.0.0.1"
port: 7443
https: true
cert_file: "C:\\Anuva\\Worker\\certs\\localhost.crt"
key_file: "C:\\Anuva\\Worker\\certs\\localhost.key"
dashboard:
enabled: true
host: "127.0.0.1"
port: 7080
https: false
admin_token_env: "ANUVA_DASHBOARD_TOKEN"
assets:
download_timeout_sec: 120
max_retries: 3
verify_checksum: true
fail_on_optional_asset_error: false
use_cache: false
output:
min_file_size_bytes: 100000
validate_with_ffprobe: false
logging:
level: "INFO"
json_logs: true
log_dir: "C:\\Anuva\\Worker\\logs"
retain_days: 14
jobs.acquisition_mode controls how jobs enter the worker:
auto: worker polls and claims jobs automatically.manual: worker only processes jobs manually claimed from Dashboard.hybrid: worker polls automatically, but Dashboard can also manually claim jobs while the worker is idle.
If allow_manual_claim_when_busy is false, the Dashboard must block manual claiming while another job is active.
20.2 Environment Variables
Required:
Optional:
Secrets must not be stored in source control.
21. Windows Service with NSSM
21.1 Service Installation
The Python Server should provide documentation and helper scripts for NSSM installation.
Example:
nssm install AnuvaUnityWorker "C:\Python311\python.exe" "-m anuva_python_server run --config C:\Anuva\Worker\config\worker.yaml"
Set working directory:
Set environment variables:
Start service:
Stop service:
21.2 Interactive User Session Requirement
Unity graphics applications may not work correctly from Windows Session 0.
The service must be configured to run in an interactive user session or via an operator login/autostart pattern where Unity can access GPU/display resources.
Recommended operational approaches:
- Use NSSM to start the Python Server under a dedicated Windows user account.
- Ensure that user can access GPU/display resources.
- Use auto-login only in controlled VM environments if required.
- Avoid running Unity as a pure Session 0 headless service unless separately validated.
- Consider Task Scheduler as an alternative for starting the worker at user login.
21.3 Service Recovery
NSSM or Windows Service Recovery should be configured to restart the Python Server if it crashes.
The Python Server itself should manage Unity restart. NSSM should manage Python restart.
22. Python Project Structure
Recommended repository structure:
anuva-python-server/
pyproject.toml
README.md
docs/
Anuva_Python_Server_Requirements.md
src/
anuva_python_server/
__init__.py
__main__.py
app.py
config.py
models.py
logging_config.py
cli.py
webapp/
__init__.py
client.py
models.py
jobs/
__init__.py
poller.py
lifecycle.py
downloader.py
workspace.py
uploader.py
manifest.py
unity/
__init__.py
process.py
zmq_client.py
protocol.py
lifecycle.py
servers/
__init__.py
content_server.py
dashboard_server.py
simulator/
__init__.py
app.py
state.py
scenarios.py
fake_client.py
models.py
uploads.py
monitoring/
__init__.py
system_metrics.py
gpu_metrics.py
health.py
utils/
__init__.py
paths.py
checksums.py
time.py
retry.py
security.py
tests/
unit/
integration/
23. CLI Requirements
The package should expose a CLI.
Recommended commands:
anuva-worker run --config C:\Anuva\Worker\config\worker.yaml
anuva-worker validate-config --config C:\Anuva\Worker\config\worker.yaml
anuva-worker poll-once --config C:\Anuva\Worker\config\worker.yaml
anuva-worker list-jobs
anuva-worker claim-job --job-id job_001
anuva-worker download-job --job-id job_001
anuva-worker launch-unity
anuva-worker stop-unity
anuva-worker send-test-render --config-path path\to\presentation_config.local.json
anuva-worker cert generate-local
anuva-worker service print-nssm-install
anuva-worker simulator run --scenario happy_path_final_render
anuva-worker simulator reset
anuva-worker simulator load-scenario happy_path_final_render
anuva-worker simulator list-scenarios
anuva-worker dashboard
The CLI can be implemented using typer or argparse.
24. Logging Requirements
24.1 Log Types
The server should maintain:
- Main server log
- Per-job Python log
- Per-job Unity log if available
- ZeroMQ message log
- Dashboard access log
- Asset download log
- Upload log
- Simulator API request log when simulator is enabled
24.2 Structured Log Fields
Each structured log event should include:
{
"timestamp": "2026-05-14T10:00:00+05:30",
"level": "INFO",
"event": "job.claimed",
"workerId": "unity-worker-01",
"jobId": "job_001",
"message": "Claimed render job"
}
Recommended fields:
timestampleveleventworkerIdjobIdpresentationIdunityPiddurationMserrorCodeexception
24.3 Sensitive Data Redaction
Logs must redact:
- API tokens
- Authorization headers
- Signed URLs
- Cookies
- Secret config values
Signed URLs should be logged as host + path hash, not full query string.
25. Security Requirements
25.1 Network Binding
Default behavior:
- ZeroMQ binds only to
127.0.0.1. - Content server binds only to
127.0.0.1. - Dashboard binds only to
127.0.0.1. - Simulator binds only to
127.0.0.1.
Do not expose local worker endpoints to public networks by default.
25.2 Dashboard Authentication
If the dashboard allows mutation actions, it must require an admin token.
For V1, read-only dashboard may be unauthenticated if bound to localhost only, but token protection is recommended.
25.3 File Serving Safety
The local content server and simulator asset server must:
- Normalize paths.
- Reject
..path traversal. - Serve only files under configured worker root or simulator root.
- Reject unknown job IDs.
- Avoid directory listing.
- Set conservative headers.
25.4 Web App Authentication
The Python Server should authenticate using a worker-scoped API token.
The token should be:
- Scoped to worker operations only.
- Stored in environment variable.
- Never logged.
- Rotatable.
26. Testing Requirements
26.1 Unit Tests
Required unit tests:
- Config loading and validation
- Job manifest generation
- Asset URL rewriting
- Checksum verification
- Error code mapping
- ZeroMQ message encoding/decoding
- Local path safety
- Web App client request construction
- Unity process state transitions
- Render job summary model validation
- Manual claim state validation
- Simulator scenario loading
26.2 Integration Tests
Required integration tests:
- Fake Web App returns queued job.
- Python claims job.
- Python downloads fake assets.
- Python writes local config.
- Fake Unity receives
render.start. - Fake Unity emits progress events.
- Fake Unity emits completed event.
- Python validates fake MP4.
- Python uploads fake MP4.
- Python marks job complete.
- Local simulator returns multiple available jobs.
- Dashboard lists available jobs.
- User manually claims a selected job.
- Simulator rejects a claim conflict.
- Simulator accepts status updates across the full lifecycle.
- Simulator stores uploaded MP4 locally.
26.3 Unity Editor Test Mode
Development workflow should support:
- Start Python Server.
- Start Unity Editor.
- Enter Play Mode.
- Unity sends
unity.ready. - Python sends test render command.
- Unity renders or simulates render.
- Python receives completion.
26.4 Failure Tests
Test these failures:
- Web App unavailable
- Job claim conflict
- Invalid job package
- Asset download 404
- Asset checksum mismatch
- Unity startup timeout
- Unity heartbeat timeout
- Unity process crash
- Render timeout
- Output MP4 missing
- Upload failure
- Job cancellation during render
26.5 Simulator Tests
Required simulator tests:
- Load scenario from disk.
- List available jobs.
- Claim job successfully.
- Reject claim for already claimed job.
- Serve local simulated assets.
- Return job package.
- Accept status update.
- Record heartbeat.
- Simulate cancellation.
- Simulate upload success.
- Simulate upload failure.
- Reset simulator state.
- Switch scenario at runtime.
- Expose simulator state for dashboard inspection.
27. Acceptance Criteria for V1
The implementation is acceptable when:
- The Python Server starts from CLI with a YAML config.
- The server can run continuously and poll the Web App.
- The server can claim a queued job.
- The server can download all job assets into a deterministic local folder.
- The server can generate
presentation_config.local.json. - The server can launch Unity EXE on Windows.
- The server can connect to Unity via ZeroMQ.
- The server can send
render.startto Unity. - The server can receive progress from Unity.
- The server can detect Unity render completion.
- The server can validate the MP4 output file.
- The server can upload the MP4 to the Web App.
- The server can mark the job completed.
- The server can fail a job with structured diagnostics.
- The server can serve local HTTPS files for Unity/Vuplex.
- The server exposes a local monitoring dashboard.
- The server can be installed and run through NSSM.
- The server can connect to Unity Editor Play Mode for testing.
- The Dashboard can list available Web App render jobs with brief summaries.
- The Dashboard can manually claim a selected render job while the worker is idle.
- Manual claiming uses the same atomic claim semantics as automatic polling.
- The Python Server can run in simulated Web App mode.
- The simulator can provide local render jobs, job packages, assets, uploads, status updates, and cancellations.
- The simulator supports success, failure, cancellation, upload failure, and Web App unavailable scenarios.
- The full Python Server + fake/simulated Web App + fake/real Unity flow can be tested locally without the real Anuva Web App.
28. Suggested Implementation Milestones
Milestone 1 — Local Worker Skeleton
Build:
- Config loader
- CLI
- Logging
- Local workspace manager
- Dashboard
/api/status - Health snapshot
No Web App or Unity integration yet.
Milestone 2 — Web App Polling and Job Workspace
Build:
- Web App client
- Polling loop
- Job claim
- Job package download
- Asset downloader
- Job manifest
- Local config writer
Use fake Web App responses if backend endpoints are not ready.
Milestone 2A — Manual Job Claiming and Dashboard Job Listing
Build:
- Available job listing client method
- Render job summary model
- Dashboard available jobs view
- Manual claim endpoint
- Manual claim UI action
- Busy-state guardrails
- Claim conflict error handling
Milestone 2B — Local Web App Simulator
Build:
- Simulator FastAPI app
- Scenario loader
- Fake Web App client
- Simulated job state machine
- Simulated asset serving
- Simulated upload handling
- Simulator Dashboard panel
- Predefined success/failure scenarios
Milestone 3 — ZeroMQ Unity Protocol
Build:
- ZeroMQ command sender
- ZeroMQ event receiver
- Protocol models
- Fake Unity simulator
- Render progress flow
Milestone 4 — Unity EXE Lifecycle
Build:
- Unity launch
- Unity readiness wait
- Unity heartbeat monitor
- Unity restart
- Unity shutdown
- Editor Play Mode connection
Milestone 5 — Render Completion and Upload
Build:
- Output validation
- Upload client
- Complete/fail job flow
- Retry policies
- Diagnostics bundle
Milestone 6 — Windows Service and Operations
Build:
- NSSM docs/scripts
- Local TLS cert helper
- Log rotation
- Operator dashboard actions
- Production hardening
29. Recommended pyproject.toml Dependencies
[project]
name = "anuva-python-server"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.110",
"uvicorn[standard]>=0.27",
"httpx>=0.26",
"pydantic>=2.6",
"pydantic-settings>=2.2",
"pyyaml>=6.0",
"pyzmq>=25.1",
"psutil>=5.9",
"GPUtil>=1.4",
"tenacity>=8.2",
"python-dotenv>=1.0",
"structlog>=24.1",
"typer>=0.9"
]
30. Example Worker State Machine
STARTING
-> IDLE
-> POLLING
-> LISTING_AVAILABLE_JOBS
-> MANUAL_CLAIM_WAIT
-> CLAIMING_JOB
-> PREPARING_JOB
-> WAITING_FOR_UNITY
-> RENDERING
-> UPLOADING
-> COMPLETING
-> IDLE
Any active state:
-> FAILING
-> IDLE
Service stop:
-> STOPPING
-> STOPPED
31. Example Render Sequence
Python Server starts
Python starts content server
Python starts dashboard server
Python starts simulator if enabled
Operator launches Unity from the Dashboard in manual EXE mode
Unity sends unity.ready
Python polls Web App or waits for manual claim
Python receives queued job or user selects a job in Dashboard
Python claims job
Python downloads config/assets
Python writes local config
Python sends render.start to Unity
Unity sends render.accepted
Unity sends render.progress events
Unity writes final.mp4
Unity sends render.completed
Python validates final.mp4
Python uploads final.mp4
Python marks job completed
Python returns to polling or manual idle state
32. Open Questions for Engineering
These should be resolved during implementation:
- Exact Payload CMS REST endpoints for worker operations.
- Answer: To be defined at a later stage.
- Whether upload is direct-to-Payload or direct-to-S3 with signed URL.
- Answer: Direct-to-S3 with Signed URL.
- Whether Unity requires local file paths or local HTTPS URLs for all assets.
- Answer: Local HTTPS URLs.
- Whether Vuplex requires trusted TLS certificates or can use self-signed localhost certs.
- Answer: Can use self-signed certs.
- Whether Unity Editor Play Mode should connect as client or server in ZeroMQ topology.
- Answer: Connect as Client.
- Whether the Web App will support
uploadFailedas a separate job state. - Answer: Yes.
- Whether preview render and final render use the same Unity executable mode.
- Answer: Yes.
- Whether thumbnail generation is Unity’s responsibility or Python’s responsibility.
- Answer: Python.
- Whether ffprobe should be bundled for output validation.
- Answer: Yes - FFMPEG will be installed on the server.
- Whether multiple workers can run on the same VM in the future.
- Answer: Yes.
- Whether the simulator should exactly mirror future Payload endpoints or remain a worker-facing abstraction.
- Answer: Should be an exact mirror.
- Whether manual Dashboard claiming should be enabled in production or limited to development/QA environments.
- Answer: Yes, should be enabled in production.
33. Local Development Principle
The Python Server must be testable before the real Web App is complete.
A developer should be able to run:
- Python Server
- Local Web App Simulator
- Fake Unity or Unity Editor Play Mode
…and exercise the complete render lifecycle locally.
The simulator is not a mock afterthought. It is a first-class development and QA tool for validating worker behavior, Unity integration, dashboard controls, and failure handling.
34. Final Implementation Principle
The Python Server should be boring, deterministic, observable, and recoverable.
It should not make creative decisions.
It should reliably execute the compiled Presentation Config, supervise Unity, preserve diagnostics, upload the result, and keep the Web App informed.
If a failure occurs, the system should always answer:
- Which job failed?
- Which worker processed it?
- What stage failed?
- What did Unity report?
- What files were involved?
- Can the job be safely retried?
End of Document