Skip to main content

L7|ESP Expression Language

Key Terms

Table 37. 

Term

Definition

Python

A high-level, interpreted, general purpose programming language with a design focus on readable and maintainable code.

L7|ESP Expression Language

An embedded programming language, based on Python, that offers a set of pre-defined functions for interacting with L7|ESP.

  • Expressions follow the form {{ <Expression> }}



Data Types

Table 38. 

Data Type

Definition

bool

Boolean - true or false.

int

Integer - positive or negative whole number.

str

String - sequence of unicode characters (alphanumeric, including punctuation, spaces, and symbols for supported human languages).

list

List - ordered collection of values, including duplicates.



An Overview of L7|ESP Expressions

L7|ESP provides the necessary building blocks to model complete business processes through the use of Entities and Protocols. However, there are times when another level of "programming" may be desired to provide dynamic content, driven by choices the End User makes while running an Experiment.

The L7|ESP Expression Language is an embedded programming language that offers deep access to L7|ESP, and is natively available in every L7|ESP instance. It is used primarily to:

  • Perform simple computations in Worksheets.

  • Generate default values and selection lists for Worksheets.

  • Pull values from one Protocol’s Worksheet and populate cells in another Worksheet.

  • Parameterize Tasks in Pipelines.

  • Define patterns for filenames when automatically registering Files.

  • Determine whether an Entity should transition to the next Workflow(s) in a Workflow Chain.

The L7|ESP Expression Language is based on the Python programming language, but limited to single-line statements. Most valid Python "one-liners" can be used as L7|ESP Expressions. The only exceptions are Expressions with syntax errors or Expressions that fail the Expression Language's security check.

Note

See Section 6.1 of the User Documentation for an explanation of this security check.

To provide access to information and support complex operations, such as "one-liners", L7|ESP supports an expanding collection of API calls that are available from the L7|ESP Expression Language.

Note

Section 6.2 of the User Documentation organizes the full list of Expressions by API endpoint.

cell(column: str, protocol: Optional[str] = None, generation: int = 0) → str

Retrieve a value from a LIMS cell.

Parameters:

  • column - the column containing the desired values.

  • protocol - name of the Protocol containing the column. If protocol is None, the current Protocol is used.

  • generation - where in the Entity-lineage to look for a value. 0 is "the uuid of the Entity in the current Protocol" -1 is the parent, -2 the grandparent, etc.

    • Values > 0 are not supported at this time.

    • generation should only be used when pulling data from a Protocol that is not present in the current Workflow.

Returns:

The associated cell value, as a string.

Note

Using the returned value in non-string context requires explicit type-casting, such as:

{{ int(cell('Concentration'))/35 }}

Examples:

# Returned from the same Protocol.
{{ cell('Concentration') }} --> '35'

# Returned from the "QC" Protocol, either in the same Workflow, or from another
# Workflow run on the same Entity.
{{ cell('Concentration', 'QC') }} --> '35'

# Returned from the "QC" Protocol from a Workflow run on the parent of the 
# current Entity.
{{ cell('Concentration', 'QC', -1) }} --> '35'

Note

Use chain_cell if strict Workflow Chain provenance is required.

tagged_value(tags: list, generation: Union[str, int] = 0, entity_uuid: Union[str, list[str]] = None) → typing.Union[str, list[str]]

Get values by tag.

Parameters:

  • tags - the list of tags. A column must match all tags to match.

  • generation - where in the Entity-lineage to look for a value. 0 is "the uuid in the current Protocol," -1 is the parent, -2 the grandparent, etc.

    • Any value supported by entity_generation may be used here.

  • entity_uuid - Entity UUID(s) to use. If None, assumed to be self.ctx['entity']['uuid']. If a list of UUIDs is provided, the result will be a list with corresponding results for each UUID.

Returns:

Corresponding column value, as a string.

Example:

# Returned from an Entity or LIMS field tagged with "esp:concentration".
{{ tagged_value(['esp:concentration']) }} --> '35'

Note

tagged_value will look at LIMS values and Entity custom fields. It should be used when a value can come from more than one (1) upstream source.

group_values(protocol: str, column: str) → list

Get the value of a column for all Entities in a single group of a grouped Protocol.

Parameters:

  • protocol - the name of the Protocol to get values from, relative to the current Workflow. If protocol is None, the current Protocol is used.

  • column - the column containing the desired values.

Returns:

Column values for all the Entities in the current row's group.

Example:

{{ group_values('Plate Prep', 'Wells') }} --> ['A1', 'B12', 'C9']

Note

grouped_value is used to get the individual values for each Entity in an Entity Group from a column in the current Protocol (or another Protocol in the same Workflow).

entity_value(varname: str, entity_uuid: Union[list[str], str] = None, generation: Union[str, int] = 0, index: int = - 1) → typing.Union[list[str], str]

Return a the value of an Entity field.

Parameters:

  • varname - the variable to return. See info panel below for details.

  • entity_uuids - the UUID(s) of the generation=0 entity. If entity_uuids is a list of UUID strings, a list of values will be returned in the same length and order as the input.

  • generation - any value that can be passed to entity_generation can be used here.

  • index - if multiple Entities are present at the specified generation, which of the Entities (by index) to use. When the generation is fetched, the Entities are ordered by creation date, so 0 would be the earliest-created Entity and -1 would be the most recently created Entity at the given generation.

Returns:

A value or list of values, depending on the shape of entity_uuids.

Examples:

# Returned from the Entity field "I7 Index" for the current Entity (LIMS context).
{{ entity_value('I7 Index') }} --> "ACGTACAT"

# Returned from the Entity field "I7 Index" for the nearest Illumina Library ancestor 
# (LIMS context).
{{ entity_value('I7 Index', generation='closestup:Illumina Library') }} --> "ACGTACAT"

In addition to custom field name, varname can also be one of the following:

Table 39. 

Varname

Description

name

Entity name.

desc

Entity description.

url

(API) URL for the Entity.

meta

Meta dict for the Entity.

uuid

Entity UUID.

cls

Entity Class.

deleted

True if the Entity is archived, otherwise false.

created_at

Created timestamp.

updated_at

Last modified timestamp.

owner

Name of the current Entity owner (normally the Entity creator).

entity_type_uuid

UUID of the Entity's Entity Type.

entity_type_name

Name of the Entity's Entity Type.

in_workflow_instance

Whether this Entity has ever been submitted to a Workflow.

barcode

Entity's barcode value.



Workflow Chain-related Expressions

next_node_choices(drop: Optional[str] = 'Finished', exclude: Optional[str] = None) → list

Returns a list of potential choices for the next Workflow Chain Node in the Workflow Chain.

  • The next choice is based on the active Workflow Chain for a given sample.

  • May only be used in the context of LIMS.

Parameters:

  • drop - a label that, if selected, means the Entity will not be routed to any further Workflows. Default value is "Finished". If None, only valid downstream Workflow Chain Node names will be available for selection.

  • exclude - a list of Workflow Chain Node choices to exclude from the drop-down. Useful in situations where a Workflow Chain Transition is present for logical clarity but will never be directly "followed".

    • For example, split/merge chains: a -> b, a -> c, b -> d; c -> d).

Returns:

The list of Workflow Chain Nodes (names, not fixed IDs) downstream from the current Workflow for the current Entity row in the Worksheet, lexicographically sorted.

Examples:

Given a **Workflow Chain** configuration of:

My Chain:
  chain:
    X:
      to:
        Y:
          if: "{{ True }}"
        Z:
          if: "{{ False }}"

{{ next_node_choices() }} --> ['Finished', 'Y', 'Z']

{{ next_node_choices(drop=None) }} --> ['Y', 'Z']

{{ next_node_choices(drop='Stop Processing') }} --> ['Stop Processing', 'Y', 'Z']

Note

next_node_choices() should only be used in Protocols that use the same Sample Set as the last Protocol in a Workflow.

is_node_selected(protocol: str = None, column: str = None, choices: Union[str, list[str]] = None, include_failed: bool = None) → bool

Workflow Chain Transition Rule function that returns True if the option(s) selected by the End User matches the target Workflow Chain Node name.

Parameters:

  • protocol - in conjunction with column, where to grab the "Next Workflow" selection(s) from. Defaults to the final Protocol in the Workflow. Uses fixed ID.

  • column - the column to grab the "Next Workflow" selection(s) from. If unspecified, L7|ESP will try "next step", "next workflow", and "next action" in turn (case-insensitive). Uses fixed ID.

  • choices - the option or options selected by the End User for downstream transition. If choices is specified, it overrides protocol and column.

    • Uses Workflow Chain Node name, NOT fixed ID.

  • include_failed - if True, failed Entities are considered for the transition. If False, failed Entities are specifically excluded. A value of None triggers the default behavior (false).

    • If the transition strategy is 'resubmit', failed Entities are considered by default.

Returns:

True if the target Workflow Chain Node was selected by the user and False otherwise.

Example:

My Chain:
  chain:
    X:
      to:
        Y:
          if: "{{ is_node_selected() }}"
        Z:
          if: "{{ is_node_selected() }}"