Job submission code and API cleanup (#127)

* Refactor add jobs and make add_job api only be one job (instead of a list)

* Renamed to JobImportHandler and misc cleanup

* Dont bury exceptions in server proxy post_job

* Update code to create child jobs in a cleaner manner
This commit is contained in:
2025-12-31 23:14:28 -06:00
committed by GitHub
parent e335328530
commit d8af7c878e
10 changed files with 267 additions and 357 deletions
+51 -17
View File
@@ -17,7 +17,7 @@ import yaml
from flask import Flask, request, send_file, after_this_request, Response, redirect, url_for
from sqlalchemy.orm.exc import DetachedInstanceError
from src.api.add_job_helpers import handle_uploaded_project_files, process_zipped_project
from src.api.job_import_handler import JobImportHandler
from src.api.preview_manager import PreviewManager
from src.distributed_job_manager import DistributedJobManager
from src.engines.engine_manager import EngineManager
@@ -32,7 +32,7 @@ logger = logging.getLogger()
server = Flask(__name__)
ssl._create_default_https_context = ssl._create_unverified_context # disable SSL for downloads
API_VERSION = "1"
API_VERSION = "0.1"
def start_api_server(hostname=None):
@@ -252,32 +252,66 @@ def status():
@server.post('/api/add_job')
def add_job_handler():
# Process request data
"""
POST /api/add_job
Add a render job to the queue.
**Request Formats**
- JSON body:
{
"name": "example.blend",
"engine": "blender",
"frame_start": 1,
"frame_end": 100,
"render_settings": {...}
"child_jobs"; [...]
}
**Responses**
200 Success
400 Invalid or missing input
500 Internal server error while parsing or creating jobs
"""
try:
if request.is_json:
jobs_list = [request.json] if not isinstance(request.json, list) else request.json
new_job_data = request.get_json()
elif request.form.get('json', None):
jobs_list = json.loads(request.form['json'])
new_job_data = json.loads(request.form['json'])
else:
return "Invalid data", 400
return "Cannot find valid job data", 400
except Exception as e:
err_msg = f"Error processing job data: {e}"
logger.error(err_msg)
return err_msg, 500
# Validate Job Data - check for required values and download or unzip project files
try:
loaded_project_local_path, referred_name = handle_uploaded_project_files(request, jobs_list,
server.config['UPLOAD_FOLDER'])
if loaded_project_local_path.lower().endswith('.zip'):
loaded_project_local_path = process_zipped_project(loaded_project_local_path)
results = []
for new_job_data in jobs_list:
new_job = DistributedJobManager.create_render_job(new_job_data, loaded_project_local_path)
results.append(new_job.json())
return results, 200
processed_job_data = JobImportHandler.validate_job_data(new_job_data, server.config['UPLOAD_FOLDER'],
uploaded_file=request.files.get('file'))
except (KeyError, FileNotFoundError) as e:
err_msg = f"Error processing job data: {e}"
return err_msg, 400
except Exception as e:
logger.exception(f"Error adding job: {e}")
err_msg = f"Unknown error processing data: {e}"
return err_msg, 500
try:
loaded_project_local_path = processed_job_data['__loaded_project_local_path']
created_jobs = []
if processed_job_data.get("child_jobs"):
for child_job_diffs in processed_job_data["child_jobs"]:
processed_child_job_data = processed_job_data.copy()
processed_child_job_data.pop("child_jobs")
processed_child_job_data.update(child_job_diffs)
child_job = DistributedJobManager.create_render_job(processed_child_job_data, loaded_project_local_path)
created_jobs.append(child_job)
else:
new_job = DistributedJobManager.create_render_job(processed_job_data, loaded_project_local_path)
created_jobs.append(new_job)
return [x.json() for x in created_jobs]
except Exception as e:
logger.exception(f"Error creating render job: {e}")
return 'unknown error', 500