Skip to content

worker_job

BaseCommand

Bases: ABC

Abstract TVPaint command which can be executed through worker.

Each command must have unique name and implemented 'execute' and 'from_existing' methods.

Command also have id which is created on command creation.

The idea is that command is just a data container on sender side send through server to a worker where is replicated one by one, executed and result sent back to sender through server.

Source code in client/ayon_tvpaint/worker/worker_job.py
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
class BaseCommand(ABC):
    """Abstract TVPaint command which can be executed through worker.

    Each command must have unique name and implemented 'execute' and
    'from_existing' methods.

    Command also have id which is created on command creation.

    The idea is that command is just a data container on sender side send
    through server to a worker where is replicated one by one, executed and
    result sent back to sender through server.
    """
    @property
    @abstractmethod
    def name(self):
        """Command name (must be unique)."""
        pass

    def __init__(self, data=None):
        if data is None:
            data = {}
        else:
            data = copy.deepcopy(data)

        # Use 'id' from data when replicating on process side
        command_id = data.get("id")
        if command_id is None:
            command_id = str(uuid4())
        data["id"] = command_id
        data["command"] = self.name

        self._parent = None
        self._result = None
        self._command_data = data
        self._done = False

    def job_queue_root(self):
        """Access to job queue root.

        Job queue root is shared access point to files shared across senders
        and workers.
        """
        if self._parent is None:
            return None
        return self._parent.job_queue_root()

    def set_parent(self, parent):
        self._parent = parent

    @property
    def id(self):
        """Command id."""
        return self._command_data["id"]

    @property
    def parent(self):
        """Parent of command expected type of 'TVPaintCommands'."""
        return self._parent

    @property
    def communicator(self):
        """TVPaint communicator.

        Available only on worker side.
        """
        return self._parent.communicator

    @property
    def done(self):
        """Is command done."""
        return self._done

    def set_done(self):
        """Change state of done."""
        self._done = True

    def set_result(self, result):
        """Set result of executed command."""
        self._result = result

    def result(self):
        """Result of command."""
        return copy.deepcopy(self._result)

    def response_data(self):
        """Data send as response to sender."""
        return {
            "id": self.id,
            "result": self._result,
            "done": self._done
        }

    def command_data(self):
        """Raw command data."""
        return copy.deepcopy(self._command_data)

    @abstractmethod
    def execute(self):
        """Execute command on worker side."""
        pass

    @classmethod
    @abstractmethod
    def from_existing(cls, data):
        """Recreate object based on passed data."""
        pass

    def execute_george(self, george_script):
        """Execute george script in TVPaint."""
        return self.parent.execute_george(george_script)

    def execute_george_through_file(self, george_script):
        """Execute george script through temp file in TVPaint."""
        return self.parent.execute_george_through_file(george_script)

communicator property

TVPaint communicator.

Available only on worker side.

done property

Is command done.

id property

Command id.

name abstractmethod property

Command name (must be unique).

parent property

Parent of command expected type of 'TVPaintCommands'.

command_data()

Raw command data.

Source code in client/ayon_tvpaint/worker/worker_job.py
123
124
125
def command_data(self):
    """Raw command data."""
    return copy.deepcopy(self._command_data)

execute() abstractmethod

Execute command on worker side.

Source code in client/ayon_tvpaint/worker/worker_job.py
127
128
129
130
@abstractmethod
def execute(self):
    """Execute command on worker side."""
    pass

execute_george(george_script)

Execute george script in TVPaint.

Source code in client/ayon_tvpaint/worker/worker_job.py
138
139
140
def execute_george(self, george_script):
    """Execute george script in TVPaint."""
    return self.parent.execute_george(george_script)

execute_george_through_file(george_script)

Execute george script through temp file in TVPaint.

Source code in client/ayon_tvpaint/worker/worker_job.py
142
143
144
def execute_george_through_file(self, george_script):
    """Execute george script through temp file in TVPaint."""
    return self.parent.execute_george_through_file(george_script)

from_existing(data) abstractmethod classmethod

Recreate object based on passed data.

Source code in client/ayon_tvpaint/worker/worker_job.py
132
133
134
135
136
@classmethod
@abstractmethod
def from_existing(cls, data):
    """Recreate object based on passed data."""
    pass

job_queue_root()

Access to job queue root.

Job queue root is shared access point to files shared across senders and workers.

Source code in client/ayon_tvpaint/worker/worker_job.py
67
68
69
70
71
72
73
74
75
def job_queue_root(self):
    """Access to job queue root.

    Job queue root is shared access point to files shared across senders
    and workers.
    """
    if self._parent is None:
        return None
    return self._parent.job_queue_root()

response_data()

Data send as response to sender.

Source code in client/ayon_tvpaint/worker/worker_job.py
115
116
117
118
119
120
121
def response_data(self):
    """Data send as response to sender."""
    return {
        "id": self.id,
        "result": self._result,
        "done": self._done
    }

result()

Result of command.

Source code in client/ayon_tvpaint/worker/worker_job.py
111
112
113
def result(self):
    """Result of command."""
    return copy.deepcopy(self._result)

set_done()

Change state of done.

Source code in client/ayon_tvpaint/worker/worker_job.py
103
104
105
def set_done(self):
    """Change state of done."""
    self._done = True

set_result(result)

Set result of executed command.

Source code in client/ayon_tvpaint/worker/worker_job.py
107
108
109
def set_result(self, result):
    """Set result of executed command."""
    self._result = result

CollectSceneData

Bases: BaseCommand

Helper command which will collect all useful info about workfile.

Result is dictionary with all layers data, exposure frames by layer ids pre/post behavior of layers by their ids, group information and scene data.

Source code in client/ayon_tvpaint/worker/worker_job.py
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
class CollectSceneData(BaseCommand):
    """Helper command which will collect all useful info about workfile.

    Result is dictionary with all layers data, exposure frames by layer ids
    pre/post behavior of layers by their ids, group information and scene data.
    """
    name = "collect_scene_data"

    def execute(self):
        from ayon_tvpaint.api.lib import (
            get_layers_data,
            get_groups_data,
            get_layers_pre_post_behavior,
            get_layers_exposure_frames,
            get_scene_data
        )

        groups_data = get_groups_data(communicator=self.communicator)
        layers_data = get_layers_data(communicator=self.communicator)
        layer_ids = [
            layer_data["layer_id"]
            for layer_data in layers_data
        ]
        pre_post_beh_by_layer_id = get_layers_pre_post_behavior(
            layer_ids, communicator=self.communicator
        )
        exposure_frames_by_layer_id = get_layers_exposure_frames(
            layer_ids, layers_data, communicator=self.communicator
        )

        self._result = {
            "layers_data": layers_data,
            "exposure_frames_by_layer_id": exposure_frames_by_layer_id,
            "pre_post_beh_by_layer_id": pre_post_beh_by_layer_id,
            "groups_data": groups_data,
            "scene_data": get_scene_data(self.communicator)
        }

    @classmethod
    def from_existing(cls, data):
        return cls(data)

ExecuteGeorgeScript

Bases: BaseCommand

Execute multiline george script in TVPaint.

Parameters:

Name Type Description Default
script_lines(list)

Lines that will be executed in george script through temp george file.

required
tmp_file_keys(list)

List of formatting keys in george script that require replacement with path to a temp file where result will be stored. The content of file is stored to result by the key.

required
root_dir_key(str)

Formatting key that will be replaced in george script with job queue root which can be different on worker side.

required
data(dict)

Raw data about command.

required
Source code in client/ayon_tvpaint/worker/worker_job.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
class ExecuteGeorgeScript(BaseCommand):
    """Execute multiline george script in TVPaint.

    Args:
        script_lines(list): Lines that will be executed in george script
            through temp george file.
        tmp_file_keys(list): List of formatting keys in george script that
            require replacement with path to a temp file where result will be
            stored. The content of file is stored to result by the key.
        root_dir_key(str): Formatting key that will be replaced in george
            script with job queue root which can be different on worker side.
        data(dict): Raw data about command.
    """
    name = "execute_george_through_file"

    def __init__(
        self, script_lines, tmp_file_keys=None, root_dir_key=None, data=None
    ):
        data = data or {}
        if not tmp_file_keys:
            tmp_file_keys = data.get("tmp_file_keys") or []

        data["script_lines"] = script_lines
        data["tmp_file_keys"] = tmp_file_keys
        data["root_dir_key"] = root_dir_key
        self._script_lines = script_lines
        self._tmp_file_keys = tmp_file_keys
        self._root_dir_key = root_dir_key
        super().__init__(data)

    def execute(self):
        filepath_by_key = {}
        script = self._script_lines
        if isinstance(script, list):
            script = "\n".join(script)

        # Replace temporary files in george script
        for key in self._tmp_file_keys:
            output_file = tempfile.NamedTemporaryFile(
                mode="w", prefix=TMP_FILE_PREFIX, suffix=".txt", delete=False
            )
            output_file.close()
            format_key = "{" + key + "}"
            output_path = output_file.name.replace("\\", "/")
            script = script.replace(format_key, output_path)
            filepath_by_key[key] = output_path

        # Replace job queue root in script
        if self._root_dir_key:
            job_queue_root = self.job_queue_root()
            format_key = "{" + self._root_dir_key + "}"
            script = script.replace(
                format_key, job_queue_root.replace("\\", "/")
            )

        # Execute the script
        self.execute_george_through_file(script)

        # Store result of temporary files
        result = {}
        for key, filepath in filepath_by_key.items():
            with open(filepath, "r") as stream:
                data = stream.read()
            result[key] = data
            os.remove(filepath)

        self._result = result

    @classmethod
    def from_existing(cls, data):
        """Recreate the object from data."""
        script_lines = data.pop("script_lines")
        tmp_file_keys = data.pop("tmp_file_keys", None)
        root_dir_key = data.pop("root_dir_key", None)
        return cls(script_lines, tmp_file_keys, root_dir_key, data)

from_existing(data) classmethod

Recreate the object from data.

Source code in client/ayon_tvpaint/worker/worker_job.py
238
239
240
241
242
243
244
@classmethod
def from_existing(cls, data):
    """Recreate the object from data."""
    script_lines = data.pop("script_lines")
    tmp_file_keys = data.pop("tmp_file_keys", None)
    root_dir_key = data.pop("root_dir_key", None)
    return cls(script_lines, tmp_file_keys, root_dir_key, data)

ExecuteSimpleGeorgeScript

Bases: BaseCommand

Execute simple george script in TVPaint.

Parameters:

Name Type Description Default
script(str)

Script that will be executed.

required
Source code in client/ayon_tvpaint/worker/worker_job.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
class ExecuteSimpleGeorgeScript(BaseCommand):
    """Execute simple george script in TVPaint.

    Args:
        script(str): Script that will be executed.
    """
    name = "execute_george_simple"

    def __init__(self, script, data=None):
        data = data or {}
        data["script"] = script
        self._script = script
        super().__init__(data)

    def execute(self):
        self._result = self.execute_george(self._script)

    @classmethod
    def from_existing(cls, data):
        script = data.pop("script")
        return cls(script, data)

JobFailed

Bases: Exception

Raised when job was sent and finished unsuccessfully.

Source code in client/ayon_tvpaint/worker/worker_job.py
16
17
18
19
20
21
22
23
24
25
26
27
28
class JobFailed(Exception):
    """Raised when job was sent and finished unsuccessfully."""
    def __init__(self, job_status):
        job_state = job_status["state"]
        job_message = job_status["message"] or "Unknown issue"
        error_msg = (
            "Job didn't finish properly."
            " Job state: \"{}\" | Job message: \"{}\""
        ).format(job_state, job_message)

        self.job_status = job_status

        super().__init__(error_msg)

ProcessTVPaintCommands

Bases: TVPaintCommands

Worker side of TVPaint Commands.

It is expected this object is created only on worker's side from existing data loaded from job.

Workfile path logic is based on 'SenderTVPaintCommands'.

Source code in client/ayon_tvpaint/worker/worker_job.py
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
class ProcessTVPaintCommands(TVPaintCommands):
    """Worker side of TVPaint Commands.

    It is expected this object is created only on worker's side from existing
    data loaded from job.

    Workfile path logic is based on 'SenderTVPaintCommands'.
    """
    def __init__(self, workfile, commands, communicator):
        super(ProcessTVPaintCommands, self).__init__(workfile)

        self._communicator = communicator

        self.commands_from_data(commands)

    def _prepare_workfile(self, workfile):
        """Preprend job queue root before passed workfile."""
        workfile = workfile.replace("\\", "/")
        job_queue_root = self.job_queue_root().replace("\\", "/")
        new_workfile = "/".join([job_queue_root, workfile])
        while "//" in new_workfile:
            new_workfile = new_workfile.replace("//", "/")
        return os.path.normpath(new_workfile)

    @property
    def communicator(self):
        """Access to TVPaint communicator."""
        return self._communicator

    def commands_from_data(self, commands_data):
        """Recreate command from passed data."""
        for command_data in commands_data:
            command_name = command_data["command"]

            klass = self.classes_by_name[command_name]
            command = klass.from_existing(command_data)
            self.add_command(command)

    def execute_george(self, george_script):
        """Helper method to execute george script."""
        return self.communicator.execute_george(george_script)

    def execute_george_through_file(self, george_script):
        """Helper method to execute george script through temp file."""
        temporary_file = tempfile.NamedTemporaryFile(
            mode="w", prefix=TMP_FILE_PREFIX, suffix=".grg", delete=False
        )
        temporary_file.write(george_script)
        temporary_file.close()
        temp_file_path = temporary_file.name.replace("\\", "/")
        self.execute_george("tv_runscript {}".format(temp_file_path))
        os.remove(temp_file_path)

    def _open_workfile(self):
        """Open workfile in TVPaint."""
        workfile = self._workfile
        print("Opening workfile {}".format(workfile))
        george_script = "tv_LoadProject '\"'\"{}\"'\"'".format(workfile)
        self.execute_george_through_file(george_script)

    def _close_workfile(self):
        """Close workfile in TVPaint."""
        print("Closing workfile")
        self.execute_george_through_file("tv_projectclose")

    def execute(self):
        """Execute commands."""
        # First open the workfile
        self._open_workfile()
        # Execute commands one by one
        # TODO maybe stop processing when command fails?
        print("Commands execution started ({})".format(len(self._commands)))
        for command in self._commands:
            command.execute()
            command.set_done()
        # Finally close workfile
        self._close_workfile()

communicator property

Access to TVPaint communicator.

commands_from_data(commands_data)

Recreate command from passed data.

Source code in client/ayon_tvpaint/worker/worker_job.py
486
487
488
489
490
491
492
493
def commands_from_data(self, commands_data):
    """Recreate command from passed data."""
    for command_data in commands_data:
        command_name = command_data["command"]

        klass = self.classes_by_name[command_name]
        command = klass.from_existing(command_data)
        self.add_command(command)

execute()

Execute commands.

Source code in client/ayon_tvpaint/worker/worker_job.py
522
523
524
525
526
527
528
529
530
531
532
533
def execute(self):
    """Execute commands."""
    # First open the workfile
    self._open_workfile()
    # Execute commands one by one
    # TODO maybe stop processing when command fails?
    print("Commands execution started ({})".format(len(self._commands)))
    for command in self._commands:
        command.execute()
        command.set_done()
    # Finally close workfile
    self._close_workfile()

execute_george(george_script)

Helper method to execute george script.

Source code in client/ayon_tvpaint/worker/worker_job.py
495
496
497
def execute_george(self, george_script):
    """Helper method to execute george script."""
    return self.communicator.execute_george(george_script)

execute_george_through_file(george_script)

Helper method to execute george script through temp file.

Source code in client/ayon_tvpaint/worker/worker_job.py
499
500
501
502
503
504
505
506
507
508
def execute_george_through_file(self, george_script):
    """Helper method to execute george script through temp file."""
    temporary_file = tempfile.NamedTemporaryFile(
        mode="w", prefix=TMP_FILE_PREFIX, suffix=".grg", delete=False
    )
    temporary_file.write(george_script)
    temporary_file.close()
    temp_file_path = temporary_file.name.replace("\\", "/")
    self.execute_george("tv_runscript {}".format(temp_file_path))
    os.remove(temp_file_path)

SenderTVPaintCommands

Bases: TVPaintCommands

Sender implementation of TVPaint Commands.

Source code in client/ayon_tvpaint/worker/worker_job.py
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
class SenderTVPaintCommands(TVPaintCommands):
    """Sender implementation of TVPaint Commands."""
    def _prepare_workfile(self, workfile):
        """Remove job queue root from workfile path.

        It is expected that worker will add it's root before passed workfile.
        """
        new_workfile = workfile.replace("\\", "/")
        job_queue_root = self.job_queue_root().replace("\\", "/")
        if job_queue_root not in new_workfile:
            raise ValueError((
                "Workfile is not located in JobQueue root."
                " Workfile path: \"{}\". JobQueue root: \"{}\""
            ).format(workfile, job_queue_root))
        return new_workfile.replace(job_queue_root, "")

    def commands_data(self):
        """Commands data to be able recreate them."""
        return [
            command.command_data()
            for command in self._commands
        ]

    def to_job_data(self):
        """Convert commands to job data before sending to workers server."""
        return {
            "workfile": self._workfile,
            "function": "commands",
            "commands": self.commands_data()
        }

    def set_result(self, result):
        commands_by_id = {
            command.id: command
            for command in self._commands
        }

        for item in result:
            command = commands_by_id[item["id"]]
            command.set_result(item["result"])
            command.set_done()

    def _send_job(self):
        """Send job to a workers server."""
        # Send job data to job queue server
        job_data = self.to_job_data()
        self.log.debug("Sending job to JobQueue server.\n{}".format(
            json.dumps(job_data, indent=4)
        ))
        job_id = self._job_queue_module.send_job("tvpaint", job_data)
        self.log.info((
            "Job sent to JobQueue server and got id \"{}\"."
            " Waiting for finishing the job."
        ).format(job_id))

        return job_id

    def send_job_and_wait(self):
        """Send job to workers server and wait for response.

        Result of job is stored into the object.

        Raises:
            JobFailed: When job was finished but not successfully.
        """
        job_id = self._send_job()
        while True:
            job_status = self._job_queue_module.get_job_status(job_id)
            if job_status["done"]:
                break
            time.sleep(1)

        # Check if job state is done
        if job_status["state"] != "done":
            raise JobFailed(job_status)

        self.set_result(job_status["result"])

        self.log.debug("Job is done and result is stored.")

commands_data()

Commands data to be able recreate them.

Source code in client/ayon_tvpaint/worker/worker_job.py
392
393
394
395
396
397
def commands_data(self):
    """Commands data to be able recreate them."""
    return [
        command.command_data()
        for command in self._commands
    ]

send_job_and_wait()

Send job to workers server and wait for response.

Result of job is stored into the object.

Raises:

Type Description
JobFailed

When job was finished but not successfully.

Source code in client/ayon_tvpaint/worker/worker_job.py
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
def send_job_and_wait(self):
    """Send job to workers server and wait for response.

    Result of job is stored into the object.

    Raises:
        JobFailed: When job was finished but not successfully.
    """
    job_id = self._send_job()
    while True:
        job_status = self._job_queue_module.get_job_status(job_id)
        if job_status["done"]:
            break
        time.sleep(1)

    # Check if job state is done
    if job_status["state"] != "done":
        raise JobFailed(job_status)

    self.set_result(job_status["result"])

    self.log.debug("Job is done and result is stored.")

to_job_data()

Convert commands to job data before sending to workers server.

Source code in client/ayon_tvpaint/worker/worker_job.py
399
400
401
402
403
404
405
def to_job_data(self):
    """Convert commands to job data before sending to workers server."""
    return {
        "workfile": self._workfile,
        "function": "commands",
        "commands": self.commands_data()
    }

TVPaintCommands

Bases: ABC

Wrapper around TVPaint commands to be able send multiple commands.

Commands may send one or multiple commands at once. Also gives api access for commands info.

Base for sender and receiver which are extending the logic for their purposes. One of differences is preparation of workfile path.

Parameters:

Name Type Description Default
workfile(str)

Path to workfile.

required
job_queue_module(JobQueueModule)

Object of AYON module JobQueue.

required
Source code in client/ayon_tvpaint/worker/worker_job.py
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
class TVPaintCommands(ABC):
    """Wrapper around TVPaint commands to be able send multiple commands.

    Commands may send one or multiple commands at once. Also gives api access
    for commands info.

    Base for sender and receiver which are extending the logic for their
    purposes. One of differences is preparation of workfile path.

    Args:
        workfile(str): Path to workfile.
        job_queue_module(JobQueueModule): Object of AYON module JobQueue.
    """
    def __init__(self, workfile, job_queue_module=None):
        self._log = None
        self._commands = []
        self._command_classes_by_name = None
        if job_queue_module is None:
            manager = AddonsManger()
            job_queue_module = manager["job_queue"]
        self._job_queue_module = job_queue_module

        self._workfile = self._prepare_workfile(workfile)

    @abstractmethod
    def _prepare_workfile(self, workfile):
        """Modification of workfile path on initialization to match platorm."""
        pass

    def job_queue_root(self):
        """Job queue root for current platform using current settings."""
        return self._job_queue_module.get_jobs_root_from_settings()

    @property
    def log(self):
        """Access to logger object."""
        if self._log is None:
            self._log = Logger.get_logger(self.__class__.__name__)
        return self._log

    @property
    def classes_by_name(self):
        """Prepare commands classes for validation and recreation of commands.

        It is expected that all commands are defined in this python file so
        we're looking for all implementation of BaseCommand in globals.
        """
        if self._command_classes_by_name is None:
            command_classes_by_name = {}
            for attr in globals().values():
                if (
                    not inspect.isclass(attr)
                    or not issubclass(attr, BaseCommand)
                    or attr is BaseCommand
                ):
                    continue

                if inspect.isabstract(attr):
                    self.log.debug(
                        "Skipping abstract class {}".format(attr.__name__)
                    )
                command_classes_by_name[attr.name] = attr
            self._command_classes_by_name = command_classes_by_name

        return self._command_classes_by_name

    def add_command(self, command):
        """Add command to process."""
        command.set_parent(self)
        self._commands.append(command)

    def result(self):
        """Result of commands in list in which they were processed."""
        return [
            command.result()
            for command in self._commands
        ]

    def response_data(self):
        """Data which should be send from worker."""
        return [
            command.response_data()
            for command in self._commands
        ]

classes_by_name property

Prepare commands classes for validation and recreation of commands.

It is expected that all commands are defined in this python file so we're looking for all implementation of BaseCommand in globals.

log property

Access to logger object.

add_command(command)

Add command to process.

Source code in client/ayon_tvpaint/worker/worker_job.py
356
357
358
359
def add_command(self, command):
    """Add command to process."""
    command.set_parent(self)
    self._commands.append(command)

job_queue_root()

Job queue root for current platform using current settings.

Source code in client/ayon_tvpaint/worker/worker_job.py
319
320
321
def job_queue_root(self):
    """Job queue root for current platform using current settings."""
    return self._job_queue_module.get_jobs_root_from_settings()

response_data()

Data which should be send from worker.

Source code in client/ayon_tvpaint/worker/worker_job.py
368
369
370
371
372
373
def response_data(self):
    """Data which should be send from worker."""
    return [
        command.response_data()
        for command in self._commands
    ]

result()

Result of commands in list in which they were processed.

Source code in client/ayon_tvpaint/worker/worker_job.py
361
362
363
364
365
366
def result(self):
    """Result of commands in list in which they were processed."""
    return [
        command.result()
        for command in self._commands
    ]