Good Practices

Here we provide some advice on how to use the Sequencer API.

Writing Sequences

Code Structure

For short scripts, putting together a Sequencer script out of a handful of functions or coroutines is perfectly fine. OTOH, in order to provide reusable code, it is preferable to group common functionality using classes.

Logging

The sequencer uses the standard python logging module logging and provides the logger seq.user.

User’s logging to a file (seq_user.log), its exact location depends on the tool used. See Sequencer Command Line Tools.

The seq.lib.getUserLogger() function returns a standard logger object.

Logging support
from seq.lib.log import getUserLogger
user_logger = getUserLogger()

def my_method():
    user_logger.info("My INFO msg")

Creating Sequences

Follow the convention outlined in Constructor Calling conventions. The class` create() method or module’s create_sequence() should get its required arguments as positional arguments or variable list of arguments (*args). Customization shall be accepted trough Keyword Arguments (**kw) in order to allow the user to setup, at least, the nodes’ name and id.

The following example shows a module level sequence ctor (create_sequence), It creates a new Sequence out of the arguments passed,

The returned sequence has an extra final step my_end_step() that was added by the constructor. The usage of keyword arguments allows to pass options to the underlying Sequence object.

Implement constructor convention
# module ctor
async def my_end_step():
    pass

def create_sequence(*args, **kw):
    return Sequence.create(*args, my_end_step, **kw)
class example
# Class Example
# must be named `Tpl`
class Tpl:
    async def my_end_step():
        pass

    @staticmethod
    create(*args, **kw):
        p = Tpl()
        return Sequence.create(*args, p.my_end_step, **kw)

Invoke other processes

It is important not to redirect the or change stdin or stdout of the sequencer tools.

To invoke other processes, and keep them detached from the sequencer process use asyncio.create_subprocess_shell() and pass options DEVNULL for stdin and stdout as shown in the example.

subprocess example
from  seq.lib.nodes import Sequence
import asyncio

async def proc_a():
    print("A")

async def proc_b():
    await asyncio.create_subprocess_shell('eog', stdin=asyncio.subprocess.DEVNULL,
                                          stdout=asyncio.subprocess.DEVNULL)

def create_sequence(*args, **kw):
    return Sequence.create(proc_a, proc_b)