Speckle Automate API Reference

This reference documents the essential APIs and interfaces for developing functions in Speckle Automate. All APIs are available in both Python and C# SDKs.
Start with the Quickstart Guide to understand the basic concepts before using this API reference.

Function Inputs

Function inputs define what users can configure when running your automation. They automatically generate forms in the web interface.

Supported Types

TypePythonC#Use Case
TextstrstringNames, descriptions, IDs
NumberfloatdoubleMeasurements, thresholds
IntegerintintCounts, indices
BooleanboolboolToggle options
SelectionEnumenumChoose from options
SecretSecretStr[Secret]API keys, passwords

Validation Attributes

ValidationPythonC#Description
RequiredField(...)[Required]Field must be provided
Lengthmin_length=1, max_length=100[MinLength(1)], [MaxLength(100)]String length limits
Rangegt=0, lt=100[Range(0, 100)]Number value limits
Patternpattern=r"^[A-Z]+$"[RegularExpression("^[A-Z]+$")]Regex validation

Example: Simple Inputs

simple_inputs.py
from speckle_automate import AutomateBase
from pydantic import Field

class FunctionInputs(AutomateBase):
    project_name: str = Field(
        title="Project Name",
        description="Enter the project identifier"
    )
    
    max_length: float = Field(
        default=10.0,
        title="Maximum Length",
        description="Maximum allowed length in meters"
    )
    
    include_analysis: bool = Field(
        default=True,
        title="Include Analysis",
        description="Whether to perform detailed analysis"
    )

Example: Dropdown Selections

dropdown_selections.py
from enum import Enum

class AnalysisType(str, Enum):
    STRUCTURAL = "structural"
    THERMAL = "thermal"
    COST = "cost"

class FunctionInputs(AutomateBase):
    analysis_type: AnalysisType = Field(
        default=AnalysisType.STRUCTURAL,
        title="Analysis Type",
        description="Select the type of analysis to perform"
    )

Example: Secure Inputs

secure_inputs.py
from pydantic import SecretStr

class FunctionInputs(AutomateBase):
    api_key: SecretStr = Field(
        title="API Key",
        description="Your external service API key"
    )

Automation Context

The AutomationContext is your function’s interface to Speckle. It provides access to data, authentication, and methods for reporting results.

Properties

automation_run_data
AutomationRunData
Metadata about the current automation run, including run ID, trigger information, and execution context
speckle_client
SpeckleClient
Pre-configured, authenticated client for Speckle API calls. Provides full access to the Speckle SDK functionality.
function_inputs
FunctionInputs
User-provided configuration values that were specified when the automation was triggered
🔧 Full SDK Access: The speckle_client property provides access to the complete Speckle SDK functionality. You can use all features from SpecklePy (Python) or SpeckleSharp (C#) within your Automate functions.

Methods

receive_version()
Base
Get the model that triggered this automation. Returns the complete Speckle data structure.
mark_run_success(message)
void
Report successful completion of the automation. Call this when your function completes successfully.
mark_run_failed(message)
void
Report business logic failure. Use this when validation fails or business rules are violated.
mark_run_exception(message)
void
Report unexpected error. Use this when an exception occurs that wasn’t part of normal business logic.
attach_error_to_objects(category, object_ids, message, metadata?)
void
Mark specific objects with errors. Useful for validation failures or processing errors on individual elements.
attach_warning_to_objects(category, object_ids, message, metadata?)
void
Add warnings to specific objects. Use for performance issues, recommendations, or non-critical problems.
attach_success_to_objects(category, object_ids, message, metadata?)
void
Mark objects as successfully processed. Useful for tracking which elements were processed correctly.
create_new_version_in_project(project_id, data, message)
string
Create a new model version with modified data. Returns the ID of the newly created version.
store_file_result(file_path, file_name)
string
Save a file as an artifact. Useful for reports, exports, or analysis results. Returns the artifact ID.

Getting Model Data

getting_model_data.py
await automate_context.receive_version() -> Base

Status Reporting

Your function must report its final status using one of these methods:
status_reporting.py
automate_context.mark_run_success(message: str)
automate_context.mark_run_failed(message: str)
automate_context.mark_run_exception(message: str)

Annotating Objects

Add status information to specific objects in the model:
annotating_objects.py
automate_context.attach_error_to_objects(category, object_ids, message, metadata=None)
automate_context.attach_warning_to_objects(category, object_ids, message, metadata=None)
automate_context.attach_success_to_objects(category, object_ids, message, metadata=None)

Creating New Model Versions

creating_versions.py
await automate_context.create_new_version_in_project(project_id, data, message) -> str

Saving Files

saving_files.py
await automate_context.store_file_result(file_path, file_name) -> str

Working with Speckle Data

Data Structure

Speckle models are directed acyclic graphs (DAGs):
  • Objects can reference other objects
  • Properties can be primitive values or object references
  • References are one-way (parent → child)
  • Common properties: elements, parameters, units, applicationId

Complete Function Example

Here’s a complete example that demonstrates all the key concepts:
complete_example.py
from speckle_automate import AutomateBase, execute_automate_function
from pydantic import Field
from enum import Enum

class AnalysisType(str, Enum):
    STRUCTURAL = "structural"
    THERMAL = "thermal"

class FunctionInputs(AutomateBase):
    analysis_type: AnalysisType = Field(
        default=AnalysisType.STRUCTURAL,
        title="Analysis Type",
        description="Type of analysis to perform"
    )
    
    max_stress: float = Field(
        default=250.0,
        title="Maximum Stress (MPa)",
        description="Maximum allowable stress",
        gt=0
    )

async def automate_function(automate_context, function_inputs):
    try:
        # Get the model data
        model_data = await automate_context.receive_version()
        
        # Find structural elements
        beams = model_data.query(lambda obj: 
            obj.speckle_type == "Objects.BuiltElements.Beam"
        )
        
        if not beams:
            automate_context.mark_run_failed("No beams found in model")
            return
        
        # Perform analysis
        failed_beams = []
        for beam in beams:
            stress = calculate_stress(beam)
            beam.parameters["calculated_stress"] = stress
            
            if stress > function_inputs.max_stress:
                failed_beams.append(beam.id)
        
        # Report results
        if failed_beams:
            automate_context.attach_error_to_objects(
                category="Stress Exceeded",
                object_ids=failed_beams,
                message=f"Stress exceeds maximum of {function_inputs.max_stress} MPa"
            )
            automate_context.mark_run_failed(f"{len(failed_beams)} beams exceed stress limit")
        else:
            automate_context.attach_success_to_objects(
                category="Analysis Complete",
                object_ids=[beam.id for beam in beams],
                message="All beams within stress limits"
            )
            automate_context.mark_run_success("Structural analysis completed successfully")
        
        # Create new version with results
        await automate_context.create_new_version_in_project(
            project_id=automate_context.automation_run_data.project_id,
            data=model_data,
            message=f"{function_inputs.analysis_type.title()} analysis results"
        )
        
    except Exception as e:
        automate_context.mark_run_exception(f"Analysis failed: {str(e)}")

def calculate_stress(beam):
    # Simplified stress calculation
    return getattr(beam, "length", 0) * 10.0

if __name__ == "__main__":
    execute_automate_function(automate_function, FunctionInputs)

Next Steps