Writing Scripts with the Seal Module
The Seal Platform allows you to write and execute your own custom Python code within the platform, enabling powerful custom solutions and automations.
If this is your first time using Python, then there are great reference materials online such as: https://docs.python.org/3.10/tutorial/
The Seal Module
The Seal module is a Python package for interacting programatically with the Seal platform.
It is automatically available in every Script's Python environment - you don't need to import it manually.
The Seal module consists of a collection of methods on the seal
object:
Getting entities
seal.get_entity(entity_id, ?version)
seal.get_entity(ref={"id: "...", "version": "..."})
Returns the entire json blob of data for that entity. The entity id can be copied from the entity's URL in Seal - it's the final section of the url, after the entity title.
Just passing an entity_id
returns the latest version or draft of the entity.
The entity id can be copied from the entity's URL in Seal - it's the final section of the url, after the entity title.
To get a specific version of an entity, include the version as a second argument. You can also pass an entity ref object instead.
Since it returns the whole json blob for the entity, you can get the entity's fields via entity["fields"]
, or a specific field via entity["fields"]["fieldName"]
.
seal.get_entity_active_version(entity_id)
Gets the data for the active version of the given entity. If no active version is found (ie the entity has never been published), an error will be thrown.
seal.get_containing_entity()
Gets the entity the script card is embedded in.
seal.get_entities_by_title(title)
Gets (non-archived) entities by their title (string). Note that exact titles are matched by default. Since multiple entities can share the same title, this returns an array. You can also search for titles containing the search string with exact=False
.
seal.search_entities(query_config)
Gets entities by searching with a query config object (dict). See the API documentation for more details on the query config schema.
Making an entity editable
seal.make_entity_editable(entity_id)
Used to make an entity editable (ie create a new draft). Returns the entire json blob of data for the new draft entity.
Reverting entity drafts
seal.revert_entities(entity_ids)
Revert multiple entity drafts to their previous published versions. All entities must be in EDITABLE status and have a previous version. Up to 500 entities can be reverted at once.
Parameters:
entity_ids
: List of entity IDs to revert (maximum 500)
Returns an array of the reverted entities.
seal.revert_containing_entity()
Revert the entity the script is embedded in to its previous published version. The entity must be in EDITABLE status and have a previous version.
Returns an array containing the reverted entity.
Validating entities
Scripts can be used to run checks before an entity is published. A script can be added as a check on a type or template for its templates or instances.
seal.get_validating_entity()
Gets the entity a script is validating.
When a validation script is run, it is classed as passing if no errors are thrown. Any of the following methods will throw an error if the assertion is not met:
validation.assertEqual(a, b)
a == b
validation.assertNotEqual(a, b)
a != b
validation.assertTrue(x)
bool(x) is True
validation.assertFalse(x)
bool(x) is False
validation.assertIs(a, b)
a is b
validation.assertIsNot(a, b)
a is not b
validation.assertIsNone(x)
x is None
validation.assertIsNotNone(x)
x is not None
validation.assertIn(a, b)
a in b
validation.assertNotIn(a, b)
a not in b
validation.assertIsInstance(a, b)
isinstance(a, b)
validation.assertNotIsInstance(a, b)
not isinstance(a, b)
User-defined errors can also be thrown to fail a validation script.
seal.throw_error(message)
Throws an error with a user-provided message.
Archiving an entity
seal.archive_entity(entity_id, archive)
Archives or unarchives an entity. The archive
parameter should be a boolean: True
to archive, False
to recover. Returns the updated entity data.
Converting an Instance to a Template
seal.convert_instance_to_template(entity_id)
Converts an instance entity into a template entity. The instance must be editable (a draft) to be converted. Returns the entire json blob of data for the new template entity.
Updating the status tag on an entity
seal.update_entity_status_tag(entity_id, status_tag)
Updates the status tag on an entity. The live entity must be in an editable state.
seal.update_upcoming_entity_status_tag(entity_id, status_tag)
Updates the upcoming status tag an entity will have when it is next published. The live entity must be in an editable state.
Getting the upcoming version info of an entity
seal.get_upcoming_version_info(entity_id)
Returns the upcoming version info of an entity. This includes the version and status tag.
Adding an entity to a change set
seal.add_entity_to_change_set(entity_id, change_set_index)
Used to add an entity to a pre-existing change set. The change_set_index
can be found in the URL when on a change set page.
Returns information about the change set the given entity now belongs to. This information includes id, index, name, status and description.
Creating Change Sets
seal.create_change_set(entity_ids, ?change_set_name)
Creates a new change set containing the provided entities. Returns information about the created change set including id, index, name, status, description and entityRefs.
Getting tags
seal.get_tags_for_entity(entity_id)
Gets the tags on an entity.
seal.get_tags(tag)
Gets the tags on an entity the script is embedded in. Can only be run from a script card.
Adding tags
seal.add_tag_to_entity(entity_id, tag)
Adds a tag to an entity. If no tag matching the input tag is found in the organisation, a new tag will be created.
seal.add_tag(tag)
Adds a tag to the entity the script is embedded in. Can only be run from a script card.
Deleting tags
seal.delete_tag(tag_name)
Remove a tag by name from the entity within which the script is embedded.
seal.delete_tag_from_entity(entity_id, tag_name)
Remove a tag by name in any entity.
Getting workflow tasks
seal.get_workflow_tasks(entity_id, ?entity_version)
Gets all workflow tasks associated with a workflow entity. Returns a list of dictionaries, each representing a full workflow task object.
seal.get_workflow_tasks_for_containing_entity()
Gets all workflow tasks for the entity that a script is embedded in. Can only be run from a script card.
Getting workflows that reference an entity
seal.get_workflows_referencing(entity_id)
Gets all workflow entities that have tasks referencing the specified entity. Returns an array of full workflow entities.
seal.get_containing_entity_workflows_referencing()
Gets all workflow entities that have tasks referencing the entity the script is embedded in. Can only be run from a script card.
Getting change sets
seal.get_change_set_for_entity(entity_id, ?version)
seal.get_change_set_for_entity(ref={"id": "...", "version": "..."})
Returns information about the change set the given entity belongs to. This information includes id, index, name, status and description. By default, we find the change set for the latest draft of the entity (if it exists).
To find the change set that a specific version of an entity belongs to, include the version as a second argument. You can also pass an entity ref object instead.
seal.get_change_set_for_containing_entity()
Gets the change set for the entity that a script is embedded in. Can only be run from a script card.
Adding fields
seal.add_field(field_name, field_type, value, allow_multiple, select_options, multi_line, formula_expression)
Add a new field to the embedded-in entity.
For specific field types, refer to this specific section in the Scripts docs.
seal.add_field_to_entity(entity_id, field_name, field_type, value, allow_multiple, select_options, multi_line, formula_expression)
Add a new field to any entity.
Updating fields
seal.update_field_value(field_name, field_value)
Update a field value in the entity the script is embedded in. Can only be run from a script card.
seal.update_field_value_in_entity(entity_id, field_name, field_value)
Update a field value in any entity.
Deleting fields
seal.delete_field(field_name)
Remove a field from the embedded-in entity. Note that the field's data will also be removed.
seal.delete_field_in_entity(entity_id, field_name)
Delete field in any entity.
Updating properties
seal.update_entity_title(entity_id, title, ?overwrite_computed_title)
Update the title of any entity. If overwrite_computed_title
is set to True and the instance has a computed title, this will be overwritten.
seal.update_containing_entity_title(title, ?overwrite_computed_title)
Update the title of the entity the script is embedded in. Can only be run from a script card.
Getting out of spec fields
seal.get_out_of_spec_fields(entity_id, ?version)
seal.get_out_of_spec_fields(ref={"id: "...", "version": "..."})
Gets the out of spec fields for the provided entity. By default, the latest version or draft of the entity is used.
To view the out of spec fields from a specific version of an entity, include the version as a second argument. You can also pass an entity ref object instead.
Handling files
seal.download_file(file_entity_id, ?version)
The file is downloaded to the local filesystem of the virtual machine instance. The value returned is the local file path as a string.
seal.upload_file(file_path, file_name, type_title, ?extract_fields_with_ai)
Uploads a file into a new entity. The provided type must have 'File' content type. Returns the entire json blob of data of the new entity.
AI data extraction
seal.extract_data_from_file(file_entity_id, version, ?=prompt)
Extract data from a file entity. See Parameters below:
file_entity_id
: ID of the file entity to extract data fromversion
: (Optional) Specific version of the file entityprompt
: (Optional, keyword-only) Custom prompt to guide the data extraction
Returns: json
Example:
data = seal.extract_data_from_file(
"9351e027-d26c-4769-a395-507f4f148cb4",
prompt="Extract all temperature readings by day"
)
Submitting Data
seal.submit_to_instance_submission_field(
"field_name",
field_values_df=pd.DataFrame([{ "field": "value", "Title": 'title'}]),
number_of_empty_instances=3
template_ref={"id": "...", "version": "..."}
)
Submit instances to a submission field in the surrounding entity.
Submit one or more instances to an instance submission field, with optional initial field values in a dataframe. If a column is called 'title' or 'Title', it will set the instances' titles of setting the values of a field called 'title' or 'Title').
You can optionally specify a number of empty instances to create.
If the submission field refers to a type, a template_ref to a template of the type must be provided.
You can also submit data to a submission table in any entity:
seal.submit_to_instance_submission_field_in_entity(entity_id, ...the same)
Creating Instances
seal.create_instance_from_template(
template_id,
?version,
field_values={ "field": "value", ... },
title='title'
)
seal.create_instance_from_template(
ref={"id: "...", "version": "..."},
field_values={ "field": "value", ... },
title='title'
)
Create an instance from a template. By default, instances are created from the latest published version of the template.
To create an instance from a specific version of a template, include the version as a second argument. You can also pass an entity ref object instead.
Parameters:
template_id
: ID of the template to create an instance fromversion
: (Optional, keyword-only) Specific version of the templatefield_values
: (Optional, keyword-only) Initial field values for the instance. The specified fields must exist on the template.
Similarly, you can also create test instances from a template:
seal.create_test_instance_from_template(
template_id,
version,
field_values={ "field": "value", ... },
)
Creating Charts
chart = alt.Chart(data).mark_bar().encode(x="x", y="y")
chart_id = seal.create_chart(chart, title="Sample Chart", type_title="Chart")
Generate a chart from an Altair chart. See parameters below:\
chart
: The Altair chart instancetitle
:The name for the charttype_title
: The name of the type to create a chart from. The content type must beChart.
Running Scripts
seal.run_script(
script_id,
?version
)
seal.run_script(
ref={"id: "...", "version": "..."},
)
Run an entity that has content type Script code
. By default, the latest version of the entity is run.
To run a specific version of a script entity, include the version as a second argument. You can also pass an entity ref object instead.
Parameters:
script_id
: ID of the script to runversion
: (Optional, keyword-only) Specific version of the script
seal.run_embedded_scripts(
entity_id,
?version,
?card_ids=["..."]
)
seal.run_embedded_scripts(
ref={"id: "...", "version": "..."},
?card_ids=["..."]
)
Parameters:
entity_id
: ID of the entity with embedded scriptsversion
: (Optional, keyword-only) Specific version of the entitycard_ids
: (Optional, keyword-only) List of specific card ids to run on the page
Run all action buttons and script cards embedded in an entity with page content. You can optionally pass in the card_ids
argument to specify which scripts in particular should be run. These IDs can be found in the page content of the entity (see the Entity Schema for more details).
Getting live backlinks
seal.get_live_backlinks(entity_id)
Returns the ids of all entities whose live data includes a reference to any version of the requested entity.
Getting trigger info
seal.get_trigger_info()
If the script is being run as a trigger, this method returns an object containing context
about the trigger run: trigger_id
and triggered_by_entity_id
.
Importing packages
Seal comes with many common Python packages pre-installed. If there are other python packages you regularly require, please contact Seal support.
These packages are automatically imported in every Script, so don't need to be manually imported:
altair
(also aliased asalt
)Chart
(alias ofaltair.Chart
)pandas
(also aliased aspd
)
To temporarily install a package when running the script:
import subprocess
subprocess.check_output("pip install {name of package}".split())
Examples
Creating and Linking Charts
This example script would be embedded in an entity containing a SUBMISSION field, with your chart data, and a REFERENCE field to embed the generated chart in.
import pandas as pd
import altair as alt
# Name of the chart entity to create
CHART_TITLE = "Growth Rate"
# Your type entity with content type: 'Chart'
# Find or create the type from org setting -> types
CHART_TYPE_NAME = "Chart"
# The containing entity REFERENCE field to append the generated file entity to
REFERENCE_FIELD_NAME = "Charts"
# Submission field name containing your chart data
SUBMISSION_FIELD_NAME = "Data"
# Submission column name to plot on the X axis
SUBMISSION_X_COLUMN = "Time"
# Submission column name to plot on the Y axis
SUBMISSION_Y_COLUMN = "Growth"
# Extract data from submission field
entity = seal.get_containing_entity()
submission_field = entity["fields"].get(SUBMISSION_FIELD_NAME, {})
submitted_refs = submission_field.get("value", [])
# Collect data from submitted entities
data = []
for ref in submitted_refs:
submitted_entity = seal.get_entity(ref=ref)
fields = submitted_entity["fields"]
timepoint = fields.get(SUBMISSION_X_COLUMN, {}).get("value")
growth_rate = fields.get(SUBMISSION_Y_COLUMN, {}).get("value")
if timepoint and growth_rate:
data.append({SUBMISSION_X_COLUMN: timepoint, SUBMISSION_Y_COLUMN: growth_rate})
# Create DataFrame and chart
df = pd.DataFrame(data)
chart = alt.Chart(df).mark_line(point=True).encode(x=SUBMISSION_X_COLUMN, y=SUBMISSION_Y_COLUMN)
# Create chart entity and link to reference field
chart_id = seal.create_chart(chart, title=CHART_TITLE, type_title=CHART_TYPE)
existing_refs = entity["fields"].get(REFERENCE_FIELD_NAME, {}).get("value", []) or []
updated_refs = existing_refs + [{"id": chart_id, "version": None}]
seal.update_field_value(REFERENCE_FIELD_NAME, updated_refs)
Last updated