Reorganize server_proxy.py

This commit is contained in:
Brett Williams
2024-08-21 01:27:42 -05:00
parent 9951915bbe
commit 193d74919f

View File

@@ -10,7 +10,6 @@ from urllib.parse import urljoin
from src.utilities.misc_helper import is_localhost from src.utilities.misc_helper import is_localhost
from src.utilities.status_utils import RenderStatus from src.utilities.status_utils import RenderStatus
from src.utilities.zeroconf_server import ZeroconfServer
status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green', status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green',
RenderStatus.NOT_STARTED: "yellow", RenderStatus.SCHEDULED: 'purple', RenderStatus.NOT_STARTED: "yellow", RenderStatus.SCHEDULED: 'purple',
@@ -26,15 +25,8 @@ LOOPBACK = '127.0.0.1'
class RenderServerProxy: class RenderServerProxy:
""" """The ServerProxy class is responsible for interacting with a remote server.
The ServerProxy class is responsible for interacting with a remote server. It provides convenience methods to request data from the server and store the status of the server.
It provides methods to request data from the server and store the status of the server.
Attributes:
system_cpu (str): The CPU type of the system.
system_cpu_count (int): The number of CPUs in the system.
system_os (str): The operating system of the system.
system_os_version (str): The version of the operating system.
""" """
def __init__(self, hostname, server_port="8080"): def __init__(self, hostname, server_port="8080"):
@@ -55,6 +47,10 @@ class RenderServerProxy:
self.system_os = None self.system_os = None
self.system_os_version = None self.system_os_version = None
# --------------------------------------------
# Basics / Connection:
# --------------------------------------------
def __repr__(self): def __repr__(self):
return f"<RenderServerProxy - {self.hostname}>" return f"<RenderServerProxy - {self.hostname}>"
@@ -73,6 +69,10 @@ class RenderServerProxy:
running_jobs = [x for x in self.__jobs_cache if x['status'] == 'running'] if self.__jobs_cache else [] running_jobs = [x for x in self.__jobs_cache if x['status'] == 'running'] if self.__jobs_cache else []
return f"{len(running_jobs)} running" if running_jobs else "Ready" return f"{len(running_jobs)} running" if running_jobs else "Ready"
# --------------------------------------------
# Requests:
# --------------------------------------------
def request_data(self, payload, timeout=5): def request_data(self, payload, timeout=5):
try: try:
req = self.request(payload, timeout) req = self.request(payload, timeout)
@@ -103,6 +103,10 @@ class RenderServerProxy:
hostname = LOOPBACK if self.is_localhost else self.hostname hostname = LOOPBACK if self.is_localhost else self.hostname
return requests.get(f'http://{hostname}:{self.port}/api/{payload}', timeout=timeout) return requests.get(f'http://{hostname}:{self.port}/api/{payload}', timeout=timeout)
# --------------------------------------------
# Background Updates:
# --------------------------------------------
def start_background_update(self): def start_background_update(self):
if self.__update_in_background: if self.__update_in_background:
return return
@@ -119,17 +123,6 @@ class RenderServerProxy:
self.__background_thread.daemon = True self.__background_thread.daemon = True
self.__background_thread.start() self.__background_thread.start()
def stop_background_update(self):
self.__update_in_background = False
def get_job_info(self, job_id, timeout=5):
return self.request_data(f'job/{job_id}', timeout=timeout)
def get_all_jobs(self, timeout=5, ignore_token=False):
if not self.__update_in_background or ignore_token:
self.__update_job_cache(timeout, ignore_token)
return self.__jobs_cache.copy() if self.__jobs_cache else None
def __update_job_cache(self, timeout=40, ignore_token=False): def __update_job_cache(self, timeout=40, ignore_token=False):
if self.__offline_flags: # if we're offline, don't bother with the long poll if self.__offline_flags: # if we're offline, don't bother with the long poll
@@ -147,15 +140,21 @@ class RenderServerProxy:
self.__jobs_cache = sorted_jobs self.__jobs_cache = sorted_jobs
self.__jobs_cache_token = status_result['token'] self.__jobs_cache_token = status_result['token']
def stop_background_update(self):
self.__update_in_background = False
# --------------------------------------------
# Get System Info:
# --------------------------------------------
def get_all_jobs(self, timeout=5, ignore_token=False):
if not self.__update_in_background or ignore_token:
self.__update_job_cache(timeout, ignore_token)
return self.__jobs_cache.copy() if self.__jobs_cache else None
def get_data(self, timeout=5): def get_data(self, timeout=5):
return self.request_data('full_status', timeout=timeout) return self.request_data('full_status', timeout=timeout)
def cancel_job(self, job_id, confirm=False):
return self.request_data(f'job/{job_id}/cancel?confirm={confirm}')
def delete_job(self, job_id, confirm=False):
return self.request_data(f'job/{job_id}/delete?confirm={confirm}')
def get_status(self): def get_status(self):
status = self.request_data('status') status = self.request_data('status')
if status and not self.system_cpu: if status and not self.system_cpu:
@@ -165,26 +164,19 @@ class RenderServerProxy:
self.system_os_version = status['system_os_version'] self.system_os_version = status['system_os_version']
return status return status
def is_engine_available(self, engine_name): # --------------------------------------------
return self.request_data(f'{engine_name}/is_available') # Get Job Info:
# --------------------------------------------
def get_all_engines(self): def get_job_info(self, job_id, timeout=5):
return self.request_data('all_engines') return self.request_data(f'job/{job_id}', timeout=timeout)
def send_subjob_update_notification(self, parent_id, subjob): def get_job_files_list(self, job_id):
""" return self.request_data(f"job/{job_id}/file_list")
Notifies the parent job of an update in a subjob.
Args: # --------------------------------------------
parent_id (str): The ID of the parent job. # Job Lifecycle:
subjob (Job): The subjob that has updated. # --------------------------------------------
Returns:
Response: The response from the server.
"""
hostname = LOOPBACK if self.is_localhost else self.hostname
return requests.post(f'http://{hostname}:{self.port}/api/job/{parent_id}/send_subjob_update_notification',
json=subjob.json())
def post_job_to_server(self, file_path, job_list, callback=None): def post_job_to_server(self, file_path, job_list, callback=None):
""" """
@@ -232,29 +224,36 @@ class RenderServerProxy:
except Exception as e: except Exception as e:
logger.error(f"An error occurred: {e}") logger.error(f"An error occurred: {e}")
def get_job_files_list(self, job_id): def cancel_job(self, job_id, confirm=False):
return self.request_data(f"job/{job_id}/file_list") return self.request_data(f'job/{job_id}/cancel?confirm={confirm}')
def download_all_job_files(self, job_id, save_path): def delete_job(self, job_id, confirm=False):
return self.request_data(f'job/{job_id}/delete?confirm={confirm}')
def send_subjob_update_notification(self, parent_id, subjob):
"""
Notifies the parent job of an update in a subjob.
Args:
parent_id (str): The ID of the parent job.
subjob (Job): The subjob that has updated.
Returns:
Response: The response from the server.
"""
hostname = LOOPBACK if self.is_localhost else self.hostname hostname = LOOPBACK if self.is_localhost else self.hostname
url = f"http://{hostname}:{self.port}/api/job/{job_id}/download_all" return requests.post(f'http://{hostname}:{self.port}/api/job/{parent_id}/send_subjob_update_notification',
return self.__download_file_from_url(url, output_filepath=save_path) json=subjob.json())
def download_job_file(self, job_id, job_filename, save_path): # --------------------------------------------
hostname = LOOPBACK if self.is_localhost else self.hostname # Renderers:
url = f"http://{hostname}:{self.port}/api/job/{job_id}/download?filename={job_filename}" # --------------------------------------------
return self.__download_file_from_url(url, output_filepath=save_path)
@staticmethod def is_engine_available(self, engine_name):
def __download_file_from_url(url, output_filepath): return self.request_data(f'{engine_name}/is_available')
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(output_filepath, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return output_filepath
# --- Renderer --- # def get_all_engines(self):
return self.request_data('all_engines')
def get_renderer_info(self, response_type='standard', timeout=5): def get_renderer_info(self, response_type='standard', timeout=5):
""" """
@@ -285,3 +284,26 @@ class RenderServerProxy:
form_data = {'engine': engine, 'version': version, 'system_cpu': system_cpu} form_data = {'engine': engine, 'version': version, 'system_cpu': system_cpu}
hostname = LOOPBACK if self.is_localhost else self.hostname hostname = LOOPBACK if self.is_localhost else self.hostname
return requests.post(f'http://{hostname}:{self.port}/api/delete_engine', json=form_data) return requests.post(f'http://{hostname}:{self.port}/api/delete_engine', json=form_data)
# --------------------------------------------
# Download Files:
# --------------------------------------------
def download_all_job_files(self, job_id, save_path):
hostname = LOOPBACK if self.is_localhost else self.hostname
url = f"http://{hostname}:{self.port}/api/job/{job_id}/download_all"
return self.__download_file_from_url(url, output_filepath=save_path)
def download_job_file(self, job_id, job_filename, save_path):
hostname = LOOPBACK if self.is_localhost else self.hostname
url = f"http://{hostname}:{self.port}/api/job/{job_id}/download?filename={job_filename}"
return self.__download_file_from_url(url, output_filepath=save_path)
@staticmethod
def __download_file_from_url(url, output_filepath):
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(output_filepath, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return output_filepath