Sending bundle versions
BundleBuilder is the authoring API for the new Speckle object model: you describe
objects, their properties and geometry, and the relationships between them, and
operations.send3 publishes the result as a new version over the /api/v2 rail.
Requires the bundle extra:
Authoring
from specklepy.api import operations
from specklepy.api.credentials import get_default_account
from specklepy.bundle import BundleBuilder, Producer
from specklepy.objects.geometry import Mesh
b = BundleBuilder(Producer(slug="my-script", version="1.0"), units="m")
walls = b.get_or_add_container_path(["Level 1", "Walls"], subtype="Category")
concrete = b.get_or_add_material("concrete", "Concrete", argb=-8355712, roughness=0.8)
level = b.get_or_add_level("L1", "Level 1", elevation=0.0)
wall = b.get_or_add_object("wall-1").set_properties(
{"Constraints": {"Base Offset": 0.5}},
name="Basic Wall",
speckle_type="Objects.Data.DataObject",
source_type="Walls",
)
wall.collection = walls
wall.level = level
wall.add_geometry(Mesh(vertices=[...], faces=[...], units="m")).material = concrete
door = b.get_or_add_object("door-1").set_properties({"Width": 0.9}, name="Door")
door.collection = walls
door.host = wall
door.parent = wall
chair = b.get_or_add_definition(
"def-chair", "Chair", lambda d: d.add_geometry(chair_mesh)
)
b.get_or_add_object("chair-1").place(chair, transform) # 16 row-major doubles
result = operations.send3(get_default_account(), project_id, model_id, b)
print(result.version_id, result.bundle_reference)
Rules, mirroring the .NET BundleBuilder:
get_or_add_*interns a node by key: the same key returns the same handle and writes nothing; the same key with different attributes raises.add_*appends a row every call (geometry, model properties, camera views).- Property setters and verbs (
wall.level = …,door.host = …,place,connect_to) emit one edge each and cannot be retracted; assigningNonebefore any edge is a no-op. set_propertieswrites an object's rows once; objects can be referenced before they are described.build()(called bysend3) injects a default scene view grouping by collection when none was declared.
Definitions with members that own their properties use add_member,
add_member_placement and add_existing_geometry; nested placements use place_nested.
operations.send3
send3(account, project_id, model_id, builder, options=None) takes an optional
SendOptions (message, file_name,
file_size_bytes, max_idle_timeout_seconds, keep_files). It creates the model ingestion (the server reserves the version id), builds and
re-keys the bundle files to that id, uploads them, and returns a
SendResult. The version becomes visible when the
server finishes ingesting; poll client.version.get for it. The builder is finished by
the call and cannot be reused. On failure the ingestion is marked failed and the error
re-raised.
API
Authoring façade over :class:ObjectsArtifactPipeline (port of the .NET
BundleBuilder).
get_or_add_* interns a node by key — the same key returns the same handle and writes
nothing; a repeat with different attributes raises. add_* appends a row every call.
Property setters and verbs emit one edge each, and an edge cannot be retracted.
BundleBuilder
BundleBuilder(
producer: Producer,
units: str,
output_dir: str | None = None,
base_name: str = DEFAULT_BASE_NAME,
)
Source code in src/specklepy/bundle/builder.py
get_or_add_container_path
get_or_add_container_path(
path: Sequence[str],
subtype: str = "Collection",
gh_topology: str | None = None,
) -> BundleContainer
Source code in src/specklepy/bundle/builder.py
get_or_add_container
get_or_add_container(
key: str,
name: str | None,
parent: BundleContainer | None,
subtype: str,
gh_topology: str | None = None,
) -> BundleContainer
Source code in src/specklepy/bundle/builder.py
get_or_add_semantic_container
get_or_add_semantic_container(
key: str,
name: str | None,
parent: BundleContainer | None,
subtype: str,
) -> BundleContainer
Semantic container (MEP System / Network / Group …) — the cont:
namespace, distinct from the scene tree.
Source code in src/specklepy/bundle/builder.py
get_or_add_object
get_or_add_object(application_id: str) -> BundleObject
Source code in src/specklepy/bundle/builder.py
try_get_object
try_get_object(application_id: str) -> BundleObject | None
try_get_geometry
try_get_geometry(
geometry_key: str,
) -> BundleGeometry | None
try_get_definition
try_get_definition(key: str) -> BundleDefinition | None
get_or_add_material
get_or_add_material(
key: str,
name: str | None,
argb: int,
opacity: float = 1.0,
metalness: float = 0.0,
roughness: float = 1.0,
emissive: int | None = None,
ior: float | None = None,
) -> BundleMaterial
Source code in src/specklepy/bundle/builder.py
get_or_add_color
get_or_add_color(argb: int) -> BundleColor
get_or_add_level
get_or_add_level(
key: str, name: str | None, elevation: float
) -> BundleLevel
Source code in src/specklepy/bundle/builder.py
get_or_add_definition
get_or_add_definition(
key: str,
name: str | None,
populate: Callable[[BundleDefinition], None]
| None = None,
) -> BundleDefinition
Source code in src/specklepy/bundle/builder.py
add_model_property
add_model_placement
add_model_placement(
default: str,
transform: Sequence[float],
units: str | None,
applied_to_geometry: bool,
*,
source: str | None = None,
options: Mapping[str, Sequence[float]] | None = None,
) -> None
Source code in src/specklepy/bundle/builder.py
add_property_set_definition
add_camera_view
scene_view
build
build() -> BundleFiles
Source code in src/specklepy/bundle/builder.py
BundleFiles
dataclass
rename_to
rename_to(version_id: str) -> BundleFiles
Source code in src/specklepy/bundle/builder.py
BundleObject
BundleObject(
builder: BundleBuilder, k: int, application_id: str
)
Source code in src/specklepy/bundle/builder.py
set_properties
set_properties(
properties: Mapping[str, Any] | None = None,
*,
name: str | None = None,
speckle_type: str | None = None,
source_type: str | None = None,
units: str | None = None,
type_key: str | None = None,
root_scalars: Iterable[tuple[str, Any]] | None = None,
) -> BundleObject
Source code in src/specklepy/bundle/builder.py
add_geometry
add_geometry(
geometry: Any, geometry_key: str | None = None
) -> BundleGeometry
Source code in src/specklepy/bundle/builder.py
add_raw_geometry
add_raw_geometry(
content: bytes,
type: str,
geometry_key: str | None = None,
) -> BundleGeometry
Source code in src/specklepy/bundle/builder.py
place
place(
definition: BundleDefinition,
transform: Sequence[float],
units: str | None = None,
key: str | None = None,
) -> BundleInstance
Source code in src/specklepy/bundle/builder.py
add_child
add_child(
child: BundleObject, ord: int | None = None
) -> None
Source code in src/specklepy/bundle/builder.py
add_assembly_member
add_assembly_member(
member: BundleObject, ord: int | None = None
) -> None
Source code in src/specklepy/bundle/builder.py
add_to_group
add_to_group(group: BundleContainer, ord: int = 0) -> None
add_to_system
add_to_system(
system: BundleContainer, ord: int = 0
) -> None
connect_to
connect_to(other: BundleObject, scope: int = 0) -> None
bounds
bounds(room: BundleObject, ord: int = 0) -> None
BundleDefinition
BundleDefinition(
builder: BundleBuilder,
k: int,
key: str,
name: str | None,
)
DEFINES / DEFINES_INSTANCE / DEFINES_MEMBER share one member-ordinal space; the (definition, ordinal) pair is what joins a member's object row to its geometry.
Source code in src/specklepy/bundle/builder.py
add_geometry
add_geometry(
geometry: Any,
geometry_key: str | None = None,
member_ord: int | None = None,
) -> BundleGeometry
Source code in src/specklepy/bundle/builder.py
add_raw_geometry
add_raw_geometry(
content: bytes,
type: str,
geometry_key: str | None = None,
member_ord: int | None = None,
) -> BundleGeometry
Source code in src/specklepy/bundle/builder.py
place_nested
place_nested(
definition: BundleDefinition,
transform: Sequence[float],
units: str | None = None,
key: str | None = None,
) -> BundleInstance
Source code in src/specklepy/bundle/builder.py
add_member
add_member(
member: BundleObject,
geometry: Iterable[Any],
member_ord: int | None = None,
) -> list[BundleGeometry]
Source code in src/specklepy/bundle/builder.py
add_member_raw_geometry
add_member_raw_geometry(
member: BundleObject,
content: bytes,
type: str,
member_ord: int,
) -> BundleGeometry
Source code in src/specklepy/bundle/builder.py
add_member_placement
add_member_placement(
member: BundleObject,
nested: BundleDefinition,
transform: Sequence[float],
units: str | None = None,
member_ord: int | None = None,
) -> BundleInstance
Source code in src/specklepy/bundle/builder.py
add_existing_geometry
add_existing_geometry(
geometry: BundleGeometry, member_ord: int | None = None
) -> None
Source code in src/specklepy/bundle/builder.py
BundleGeometry
BundleGeometry(builder: BundleBuilder, k: int, ord: int)
Source code in src/specklepy/bundle/builder.py
BundleContainer
BundleContainer(
builder: BundleBuilder,
k: int,
key: str,
name: str | None,
subtype: str,
parent: BundleContainer | None,
)
Source code in src/specklepy/bundle/builder.py
BundleLevel
BundleLevel(
builder: BundleBuilder,
k: int,
key: str,
name: str | None,
elevation: float,
)
Source code in src/specklepy/bundle/builder.py
BundleMaterial
BundleMaterial(
builder: BundleBuilder,
k: int,
key: str,
name: str | None,
argb: int,
)
Source code in src/specklepy/bundle/builder.py
BundleColor
BundleColor(builder: BundleBuilder, k: int, argb: int)
BundleInstance
BundleInstance(
builder: BundleBuilder,
k: int,
definition: BundleDefinition,
)