Files
IFC-Exporter/utils/receiver.py
T
2026-03-03 10:06:20 +01:00

69 lines
2.5 KiB
Python

# =============================================================================
# receiver.py
# Connects to Speckle and receives the root Base object for a given version.
# =============================================================================
from specklepy.api.client import SpeckleClient
from specklepy.api.credentials import get_default_account
from specklepy.api import operations
from specklepy.transports.server import ServerTransport
import utils.config as config
def get_client() -> SpeckleClient:
"""
Create and authenticate a SpeckleClient.
Uses a personal access token from config.py.
To use your local Speckle Manager account instead, swap to get_default_account().
"""
client = SpeckleClient(host=config.SPECKLE_HOST)
if config.SPECKLE_TOKEN and config.SPECKLE_TOKEN != "YOUR_PERSONAL_ACCESS_TOKEN":
client.authenticate_with_token(config.SPECKLE_TOKEN)
else:
# Fallback: use account from Speckle Manager desktop app
account = get_default_account()
if account is None:
raise RuntimeError(
"No Speckle account found. Either set SPECKLE_TOKEN in config.py "
"or log in via Speckle Manager."
)
client.authenticate_with_account(account)
return client
def receive_version(project_id: str, version_id: str):
"""
Receive the root Base object from a Speckle version.
Args:
project_id: The Speckle project (stream) ID.
version_id: The version (commit) ID to receive.
Returns:
A specklepy Base object — the root of the object graph.
"""
client = get_client()
print(f"🔗 Connecting to {config.SPECKLE_HOST}...")
print(f"📦 Receiving project={project_id} version={version_id}")
# Get version metadata to find the referenced object ID
version = client.version.get(version_id,project_id)
referenced_object_id = version.referenced_object
# Download the full object graph
transport = ServerTransport(stream_id=project_id, client=client)
base = operations.receive(referenced_object_id, transport)
# Read units from the root object
units = getattr(base, "units", config.DEFAULT_UNITS) or config.DEFAULT_UNITS
# IFC file is declared in MILLIMETRES — no conversion needed.
# All geometry stays in source units (mm). scale=1.0 means "keep as-is".
scale = 1.0
print(f"✅ Received root object units={units} scale=1.0 (IFC declared as mm)")
return base, scale