diff --git a/server.py b/server.py index 91dc17f..22c5d04 100755 --- a/server.py +++ b/server.py @@ -10,7 +10,7 @@ from datetime import datetime import requests import yaml -from flask import Flask, jsonify, request, render_template +from flask import Flask, request, render_template from werkzeug.utils import secure_filename from lib.render_job import RenderJob @@ -60,6 +60,11 @@ def unregister_client(): return "Success" if x else "Fail" +@app.get('/clients') +def render_clients(): + return RenderManager.render_clients + + @app.get('/full_status') def full_status(): full_results = {'timestamp': datetime.now().isoformat(), 'servers': {}} @@ -106,9 +111,14 @@ def add_job(): # handle request values from HTML pages - may deprecate if HTML is not used or can pass JSON from HTML request_params = request.values + json_string = request.form.get('json', None) + if not json_string: + return 'missing json data', 400 + + request_params = json.loads(json_string) renderer = request_params.get("renderer", None) input_path = request_params.get("input", None) - output_path = request_params.get("output", "test-output.mp4") + output_path = request_params.get("output", None) priority = int(request_params.get('priority', 2)) args = request_params.get('args', {}) client = request_params.get('client', RenderManager.host_name) @@ -120,13 +130,13 @@ def add_job(): if None in [renderer, input_path or (uploaded_file and uploaded_file.filename), output_path]: err_msg = 'Cannot add job: Missing required parameters' logger.error(err_msg) - return {'error': err_msg} + return err_msg, 400 - # cleanup args from html form and convert them into an args dict - for key, val in request_params.items(): - if key.startswith(renderer): - cleaned_key = key.split('+')[-1] - args[cleaned_key] = val + # # cleanup args from html form and convert them into an args dict + # for key, val in request_params.items(): + # if key.startswith(renderer): + # cleaned_key = key.split('+')[-1] + # args[cleaned_key] = val # handle uploaded files if uploaded_file and uploaded_file.filename: @@ -139,9 +149,7 @@ def add_job(): local_path = os.path.join(job_dir, secure_filename(uploaded_file.filename)) uploaded_file.save(local_path) input_path = local_path - - # todo: finish output_path - currently placeholder data - output_path = os.path.join(job_dir, uploaded_file.filename + "-output.mp4") + output_path = os.path.join(job_dir, os.path.basename(output_path)) # local renders if client == RenderManager.host_name: @@ -149,8 +157,9 @@ def add_job(): try: render_job = RenderWorkerFactory.create_worker(renderer, input_path, output_path, args) except ValueError as e: - logger.exception(e) - return {'error': str(e)}, 400 + err_msg = f"Error creating job: {str(e)}" + logger.exception(err_msg) + return err_msg, 400 new_job = RenderJob(render_job, priority=priority, custom_id=custom_id) RenderManager.add_to_render_queue(new_job, force_start=force_start) @@ -163,47 +172,34 @@ def add_job(): # see if host is available if RenderManager.is_client_available(client): - if args and renderer == 'blender' and args.get('pack_files', False): - from utilities.blender_worker import pack_blender_files - new_path = pack_blender_files(path=input_path) - if new_path: - logger.info(f'Packed Blender file successfully: {new_path}') - input_path = new_path - else: - err_msg = f'Failed to pack Blender file: {input_path}' - logger.error(err_msg) - return {'error': err_msg}, 400 - # call uploader on remote client try: - job_files = {'file': open(input_path, 'rb')} - job_data = request.json - job_data['input'] = input_path logger.info(f"Uploading file {input_path} to client {client}") - response = requests.post(f"http://{client}:8080/add_job", files=job_files, data=job_data) + job_data = request.json + response = post_job_to_server(input_path, job_data) if response.ok: logger.info("Job submitted successfully!") return response.json() if response.json() else "Job ok" else: - return {'error', 'Job rejected by client'}, 400 + return 'Job rejected by client', 403 except requests.ConnectionError as e: err_msg = f"Error submitting job to client: {client}" logger.error(err_msg) - return {'error', err_msg}, 400 + return err_msg, 500 else: # client is not available err_msg = f"Render client '{client}' is unreachable" logger.error(err_msg) - return {'error', err_msg}, 400 + return err_msg, 503 else: err_msg = f"Unknown render client: '{client}'" logger.error(err_msg) - return {'error', err_msg}, 400 + return err_msg, 400 except Exception as e: logger.exception(f"Unknown error adding job: {e}") - return {'error', 'cannot add job'} + return 'unknown error', 500 @app.get('/cancel_job') @@ -211,24 +207,24 @@ def cancel_job(): job_id = request.args.get('id', None) confirm = request.args.get('confirm', False) if not job_id: - return {'error': 'job id not found'}, 400 + return 'job id not found', 400 elif not confirm: - return {'error': 'confirmation required'}, 400 + return 'confirmation required', 400 else: found = [x for x in RenderManager.render_queue if x.id == job_id] if len(found) > 1: # logger.error('Multiple jobs found for ID {}'.format(job_id)) - return jsonify({'error': 'multiple jobs found for ID {}'.format(job_id)}) + return f'multiple jobs found for ID {job_id}', 400 elif found: success = RenderManager.cancel_job(found[0]) - return jsonify({'result': success}) - return {'error': 'job not found'}, 400 + return success + return 'job not found', 400 @app.get('/clear_history') def clear_history(): RenderManager.clear_history() - return {'result': True} + return 'success' @app.route('/status') @@ -247,6 +243,15 @@ def upload_file_page(): supported_renderers=RenderWorkerFactory.supported_renderers()) +def post_job_to_server(input_path, job_json, client, server_port=8080): + # Pack job data and submit to server + job_files = {'file': (os.path.basename(input_path), open(input_path, 'rb'), 'application/octet-stream'), + 'json': (None, json.dumps(job_json), 'application/json')} + + req = requests.post(f'http://{client}:{server_port}/add_job', files=job_files) + return req + + def start_server(background_thread=False): def eval_loop(delay_sec=1):