Skip to main content

Edit Resource Properties

Read and change typed property values on an existing resource.

Property values are read through the resource schema and changed through a resource builder. Editing a schema you fetched from a query does not persist anything by itself.

For the complete set of access forms, including step parameters, see Property and Parameter Access.

Read values

plate = namespace.query_maker().resources().filter(name="Plate 001").first()

rows = plate.properties.dimensions.rows.value
unit = plate.properties.dimensions.rows.unit

The trailing .value is required. Without it you get the wrapper object that holds the value and its unit, which prints like the value but does not compare equal to it.

Bracket access accepts either the normalized slug or the original attribute name, and .get(name) returns None for a missing attribute instead of raising:

group = plate.properties["dimensions"]

rows = group["rows"].value
rows = group.get("rows").value

Change values on a mutable resource

Assign the raw value inside a builder block. There is no .value on the left-hand side:

with namespace.build_resource(resource_id=plate.id) as builder:
    builder.resource.properties.dimensions.rows = 16

The builder validates values against the template and persists the aggregate on successful context-manager exit. An exception rolls the change back.

Change values on an active resource

ImportantEdits to an active resource go to a copy by default

A resource becomes frozen once it is ACTIVE. Saving builder edits to it creates a new mutable copy that records its origin; the original is unchanged. Because queries return only active resources, any resource you located with a query is already frozen.

To change the active resource itself, opt in to editing in place:

with namespace.build_resource(resource_id=plate.id, in_place=True) as builder:
    builder.resource.properties.dimensions.rows = 16

The resource keeps its ID and status and its revision increments. Process runs that reference it see the new values.

To keep the original and work on a revision instead, copy it explicitly:

from recap import ResourceCopyOptions

copied = namespace.copy_resource(
    source_resource_id=plate.id,
    options=ResourceCopyOptions(name="Plate 001 Revision"),
)

with namespace.build_resource(resource_id=copied.id) as builder:
    builder.resource.properties.dimensions.rows = 16
    builder.finalize()

The copy records its origin, so lineage from the revision back to the original is preserved. See Manage Resource Lifecycle for both procedures.

Units and metadata

Setting a value preserves the attribute’s existing unit. Set the unit explicitly when an update changes its meaning:

with namespace.build_resource(resource_id=copied.id) as builder:
    builder.resource.properties.dimensions.rows = 16
    builder.resource.properties.dimensions.rows.unit = "count"

Template metadata can constrain numeric ranges or enumerate allowed values. Invalid values fail validation before the mutation is committed.