Skip to main content

RSWall Python Scripting

Python API for controlling RSWall programmatically via gRPC.

Three-repo onboarding (RSWall + this package + MCP / RSInsight): ../rsgpt-mcp-rswall/docs/developer-onboarding.md.

Architecture

RSWall scripting uses a client-server architecture where Python communicates with the RSWall application via gRPC (Google Remote Procedure Call). The RSWall C# application hosts a gRPC server using the Rocscience.Scripting.RPCSupport.Net NuGet package, which provides infrastructure for thread marshaling, object reference management, and UI notification handling. Protocol Buffer (.proto) files define the service contracts and are compiled into both C# server stubs and Python client stubs.

This Python package (rswall) wraps the generated gRPC stubs in a user-friendly API. When you call methods like modeler.openFile() or material.setUnitWeight(), the package translates these into gRPC calls to the RSWall server, which executes the operations on the main UI thread and returns results. Object references (projects, materials) are tracked by GUID strings that map to actual C# objects on the server.

Installation

Development (editable install from this repo):

pip install -e .

Production installs will use the internal Rocscience PyPI feed (same pattern as DipsScripting), e.g. pip install RSWallScripting==1.006, once published.

Import classes from submodules:

from rswall.RSWallModeler import RSWallModeler
from rswall.Wall import Wall

Quick Start (Development)

1. Start RSWall with Scripting Server

Navigate to the RSWall build output and start with the scripting flag: Notice that the location of the path can be different depending on where you keep your RSWall Repo. This is also assuming that this build has scriptting capabilities.

cd C:\Users\user-name\source\repos\RSWall\RSWall\bin\x64\Release\net472
RSWall.exe -startScriptingServer 60067

2. Verify Server is Listening

netstat -ano | findstr 60067

You should see a line showing the port is in LISTENING state.

3. Run a Python Script

from rswall.RSWallModeler import RSWallModeler

# Path to your test file
FILE_PATH = r"C:\path\to\your\file.rswall"

# Connect to RSWall
print("Connecting to RSWall on port 60067...")
modeler = RSWallModeler(port=60067)
print("✓ Connected!")

# Open file (will appear in RSWall UI)
print(f"\nOpening file: {FILE_PATH}")
wall = modeler.openFile(FILE_PATH)
print("✓ File opened!")

# Get all materials and display their unit weights (project native units)
units = wall.getProjectUnits()
uw_unit = units["unitWeightUnit"]
print("\nMaterials in project:")
materials = wall.getAllMaterials()
for mat in materials:
    unit_weight = mat.getUnitWeight()
    print(f"  - {mat.name}: {unit_weight} {uw_unit}")

# Modify the first material's unit weight
if materials:
    first_material = materials[0]
    print(f"\nChanging '{first_material.name}' unit weight...")
    print(f"  Before: {first_material.getUnitWeight()} {uw_unit}")
    first_material.setUnitWeight(19.69)
    print(f"  After:  {first_material.getUnitWeight()} {uw_unit}")

Expected Results

When you run the script:

  1. RSWall opens the specified file - You'll see the project appear in the RSWall application window
  2. Materials are listed - The script prints all soil materials with their unit weights in project native units
  3. Unit weight is modified - The first material's unit weight changes (value shown with unit label from getProjectUnits)
  4. Change is visible in UI - If you check the material properties in RSWall, you'll see the updated value

API Reference

The full scripting reference manual is built with Sphinx from docs/:

pip install -e ".[docs]"
python -m sphinx -W -b html docs docs/_build/html

The site has two tracks (same layout as RSPile):

  • rswall package — one API page per public class/helper
  • Python Script Examples — code snippets + downloadable ExampleModel.rswall

Published site (once GitHub Pages is enabled): https://rocscience.github.io/rswall-scripting/

See docs/PUBLISHING.md for org publishing steps.

Note: All numeric wire values use the project's native unit system. Call wall.getProjectUnits() after opening a file to read unit labels. No client-side conversion is applied.

Troubleshooting

Issue Solution
"Connection refused" Ensure RSWall is running with -startScriptingServer 60067
"File not found" Use full absolute path to the .rswall file
Port not listening Check if another process is using port 60067

Requirements

  • Python 3.8+
  • RSWall with scripting support (built from source with Phases 1-2 complete)
  • Windows

Future Development

To expose additional RSWall functions (e.g., setting soil name), follow these steps:

Step 1: Update the Proto File (RSWall repo)

Add new messages and RPC method to the appropriate .proto file in RSWall/RPCServices/protoFiles/.

Example - adding SetName to MaterialService.proto:

// Add new messages
message SetNameRequest {
    string materialId = 1;
    string name = 2;
}

message SetNameResponse {
    bool success = 1;
}

// Add to the service block
service MaterialService {
    // ... existing methods ...
    rpc SetName(SetNameRequest) returns (SetNameResponse);
}

Step 2: Build RSWall (generates C# stubs)

Build the RSWall solution in Visual Studio. The Grpc.Tools NuGet package automatically generates C# code from the .proto files into the obj/ folder.

Step 3: Implement C# Server Logic (RSWall repo)

a) Add service method in RSWall/RPCServices/serviceImplementations/MaterialServiceImpl.cs:

public override Task<SetNameResponse> SetName(
    SetNameRequest request,
    ServerCallContext context) =>
    ScriptingData.RunScriptingFunction(request, context, SetNameImpl);

private SetNameResponse SetNameImpl(SetNameRequest request)
{
    MaterialLogic.SetName(request.MaterialId, request.Name, ScriptingData);
    return new SetNameResponse { Success = true };
}

b) Add business logic in RSWall/RPCServices/staticLogic/MaterialLogic.cs:

public static void SetName(string materialId, string name, ScriptingData scriptingData)
{
    var soil = GetSoilData(materialId, scriptingData);
    soil.Name = name;
}

Step 4: Copy Proto File to RSWallScripting

Copy the updated .proto file from RSWall/RPCServices/protoFiles/ to RSWallScripting/src/rswall/generatedFiles/.

Step 5: Generate Python Stubs (RSWallScripting repo)

.\tools\generate_stubs.ps1

That regenerates every *_pb2.py / *_pb2_grpc.py from the .proto files in src/rswall/generatedFiles/ and patches the imports to be package-relative.

Step 6: Add Python Wrapper Method (RSWallScripting repo)

Add user-friendly method in src/rswall/Material.py:

def setName(self, name: str) -> None:
    """Set the name of the material."""
    request = MaterialService.SetNameRequest(
        materialId=self._objectId,
        name=name
    )
    response = self._client.callFunction(
        self._materialService.SetName, request
    )
    if not response.success:
        raise RuntimeError("Failed to set name")
    self._name = name  # Update local cache

Summary

Step Location Action
1 RSWall .proto Define messages + RPC
2 RSWall (VS) Build → C# stubs generated
3 RSWall ServiceImpl + Logic Implement server-side code
4 Copy .proto RSWall → RSWallScripting
5 RSWallScripting Generate Python stubs
6 RSWallScripting Material.py Add Python wrapper

Metadata

Release files for RSWallScripting 1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for RSWallScripting 1.6
File Size Uploaded Provenance
rswallscripting-1.6.tar.gz 170.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for RSWallScripting 1.6
File Interpreter ABI Platform
rswallscripting-1.6-py3-none-any.whl Python 3 none any Details

Total release size: 345.4 kB

Release files / rswallscripting-1.6.tar.gz

Download URL rswallscripting-1.6.tar.gz
Size 170.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ab0b2019a4e59a92baff50e0f02af4ff8a46f6f2d673c819db2a60afaeec6800
BLAKE2b-256 checksum
How to use checksums
4c04dddf232bb6e19d46b8837042f8d89fd81387765306e0cc32ba9df7ac2c9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Release files / rswallscripting-1.6-py3-none-any.whl

Download URL rswallscripting-1.6-py3-none-any.whl
Size 174.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3858607bb64df9adb850db984de55b3ed9fe03531162eeb102c1b5829bb7491b
BLAKE2b-256 checksum
How to use checksums
fd9b4cb74e337db4f01451515bcae2453dc3bf49b301a4e83d647a1e07ea9397
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.0

Security for RSWallScripting 1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.6 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page