Skip to content

Python SDK

The Python SDK submits statements to a running native SpatialEngine over gRPC.

Studio starts an engine and configures the connection for your project. In a custom application, start the supplied engine binary and install its matching SDK wheel.

Connect

Read the engine’s startup output for its gRPC port. The default is 50051.

import spatialengine

with spatialengine.Client("localhost:50051") as client:
    message = client.std.print(message="Connected to SpatialEngine")
    print(message)

spatialengine.connect() uses FDK_HOST and FDK_PORT, with defaults of localhost and 50051. Studio supplies those values. The client waits for startup for up to 120 seconds by default.

Draw a shape

This example creates a temporary cube. Open a viewport to see it.

import spatialengine
from spatialengine.types.std.math import Quat, Vec3

with spatialengine.connect() as client:
    cube = client.std.scene.shape.spawn_cube(
        translation=Vec3(x=0.0, y=0.0, z=0.0),
        rotation=Quat(x=0.0, y=0.0, z=0.0, w=1.0),
        half_extents=1.0,
    )
    print(cube)

Scene shapes are temporary. Use project objects for saved, undoable content.

Return values and failures

Calls return typed values directly. Messages and variants live under spatialengine.types. Engine failures raise EngineError subclasses.

import spatialengine

with spatialengine.connect() as client:
    try:
        client.std.viewport.camera.zoom_extents(viewport="main")
    except spatialengine.EngineError as error:
        print(error.message)

A camera statement needs an active viewport. Use the label assigned by your page. Reads requiring one viewport fail when the label selects none or several.

Async code

AsyncClient exposes the same statements as awaitable calls. Use it from an active event loop.

import asyncio
import spatialengine

async def main():
    async with spatialengine.connect_async() as client:
        messages = await asyncio.gather(
            client.std.print(message="First independent call"),
            client.std.print(message="Second independent call"),
        )
        print(messages)

asyncio.run(main())

Independent calls can run concurrently. Await dependent calls in sequence. A transaction groups edits into one undo entry; it does not establish an order between concurrent calls.

Transactions and undo covers commits, cancellation, and transaction modes.