From 90478f256ddb1d6ff66396350d29069c12cebe24 Mon Sep 17 00:00:00 2001 From: Brett Williams Date: Tue, 20 Aug 2024 22:19:48 -0500 Subject: [PATCH] Add docstrings to base_engine.py and base_worker.py --- src/distributed_job_manager.py | 17 ++++++--- src/engines/core/base_engine.py | 65 +++++++++++++++++++++++++++++++-- src/engines/core/base_worker.py | 17 ++++++++- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/distributed_job_manager.py b/src/distributed_job_manager.py index 68098e1..39ec380 100644 --- a/src/distributed_job_manager.py +++ b/src/distributed_job_manager.py @@ -130,10 +130,8 @@ class DistributedJobManager: @classmethod def create_render_job(cls, job_data, loaded_project_local_path): - """ - Creates render jobs. - - This method job data and a local path to a loaded project. It creates and returns new a render job. + """Creates render jobs. Pass in dict of job_data and the local path to the project. It creates and returns a new + render job. Args: job_data (dict): Job data. @@ -189,8 +187,7 @@ class DistributedJobManager: @classmethod def handle_subjob_update_notification(cls, local_job, subjob_data): - """ - Responds to a notification from a remote subjob and the host requests any subsequent updates from the subjob. + """Responds to a notification from a remote subjob and the host requests any subsequent updates from the subjob. Args: local_job (BaseRenderWorker): The local parent job worker. @@ -214,6 +211,14 @@ class DistributedJobManager: @classmethod def wait_for_subjobs(cls, parent_job): + """Check the status of subjobs and waits until they are all finished. Download rendered frames from subjobs + when they are completed. + + Args: + parent_job: Worker object that has child jobs + + Returns: + """ logger.debug(f"Waiting for subjobs for job {parent_job}") parent_job.status = RenderStatus.WAITING_FOR_SUBJOBS statuses_to_download = [RenderStatus.CANCELLED, RenderStatus.ERROR, RenderStatus.COMPLETED] diff --git a/src/engines/core/base_engine.py b/src/engines/core/base_engine.py index 57fbf5c..d7875ae 100644 --- a/src/engines/core/base_engine.py +++ b/src/engines/core/base_engine.py @@ -40,8 +40,21 @@ class BaseRenderEngine(object): logger.exception(e) return path + # -------------------------------------------- + # Methods to override in subclasses + # -------------------------------------------- + def version(self): - raise NotImplementedError("version not implemented") + """ + Should be overridden to return the version number. + + Returns: + str: Version number. + + Raises: + NotImplementedError: If not overridden. + """ + raise NotImplementedError(f"version not implemented for {self.__class__.__name__}") def supported_extensions(self): return [] @@ -58,7 +71,18 @@ class BaseRenderEngine(object): def ui_options(system_info): # override to return options for ui return {} - def get_help(self): # override if renderer uses different help flag + def get_help(self): + """Retrieves the help documentation for the renderer. + + This method runs the renderer's help command (default: '-h') and captures the output. + Override this method if the renderer uses a different help flag. + + Returns: + str: The help documentation as a string. + + Raises: + FileNotFoundError: If the renderer path is not found. + """ path = self.renderer_path() if not path: raise FileNotFoundError("renderer path not found") @@ -68,7 +92,22 @@ class BaseRenderEngine(object): return help_doc def get_project_info(self, project_path, timeout=10): - raise NotImplementedError(f"get_project_info not implemented for {self.__name__}") + """Retrieves information about the project. + + This method should be overridden in a subclass to implement the logic for extracting + project information from the given project path. + + Args: + project_path (str): The path to the project file. + timeout (int, optional): The maximum time (in seconds) to wait for the operation. Default is 10 seconds. + + Returns: + dict: A dictionary containing project information (subclasses should define the structure). + + Raises: + NotImplementedError: If the method is not overridden in a subclass. + """ + raise NotImplementedError(f"get_project_info not implemented for {self.__class__.__name__}") @classmethod def get_output_formats(cls): @@ -78,7 +117,25 @@ class BaseRenderEngine(object): pass def system_info(self): - pass + """Return additional information about the system specfic to the engine (configured GPUs, render engines, etc) + + Returns: + dict: A dictionary with engine-specific system information + """ + return {} def perform_presubmission_tasks(self, project_path): + """Perform any pre-submission tasks on a project file before uploading it to a server (pack textures, etc.) + + Override this method to: + 1. Copy the project file to a temporary location (DO NOT MODIFY ORIGINAL PATH). + 2. Perform additional modifications or tasks. + 3. Return the path to the modified project file. + + Args: + project_path (str): The original project file path. + + Returns: + str: The path to the modified project file. + """ return project_path diff --git a/src/engines/core/base_worker.py b/src/engines/core/base_worker.py index 9676865..9ab5c94 100644 --- a/src/engines/core/base_worker.py +++ b/src/engines/core/base_worker.py @@ -424,7 +424,22 @@ class BaseRenderWorker(Base): return 0 def _parse_stdout(self, line): - raise NotImplementedError("_parse_stdout not implemented") + """Parses a line of standard output from the renderer. + + This method should be overridden in a subclass to implement the logic for processing + and interpreting a single line of output from the renderer's standard output stream. + + On frame completion, the subclass should: + 1. Update value of self.current_frame + 2. Call self._send_frame_complete_notification() + + Args: + line (str): A line of text from the renderer's standard output. + + Raises: + NotImplementedError: If the method is not overridden in a subclass. + """ + raise NotImplementedError(f"_parse_stdout not implemented for {self.__class__.__name__}") def time_elapsed(self): return get_time_elapsed(self.start_time, self.end_time)