Python Sandbox

Run reusable models, engineering calculations and drawing automation with Scopture's shared Python runtime.

Scopture’s Python sandbox runs Model Elements and drawing automation in a managed Python 3.12 environment. Use it to compute geometry, analyse engineering models, produce visual results and apply deliberate drawing updates.

Where Code Runs

  • Desktop: the installed local sandbox is the default for both local and remote drawings, including background output and thumbnail generation. Remote drawing access still requires authorization.
  • CLI: scopture run-python uses the installed desktop sandbox when available, including for remote IDs. Pass --server to request cloud execution explicitly.
  • Browser and mobile: an authorized cloud drawing on an entitled paid plan uses the server worker. Offline Python execution requires desktop.

Desktop and server derive their dependencies from the same sandbox pyproject.toml and lockfile and use the same worker implementation. Native wheels, operating-system libraries and graphics backends still require platform-specific verification.

Desktop jobs wait in a local queue. Up to four workers run at once, reduced according to available CPU and memory while reserving resources for the app. Queued jobs do not fail just because all worker slots are occupied.

The desktop installer includes uv and a locked runtime profile. First preparation installs Python and its dependencies into Scopture’s user storage. Later launches reuse the prepared environment offline; updates reuse unchanged environments and uv’s package cache. Scopture does not install packages into your host Python or use arbitrary user site-packages. Development uses the workspace ducpy; distribution builds resolve and lock the published version when packaging.

Two Execution Contexts

A Model Element runs its Python source and imports drawing-local dependencies. Its output is a persisted artifact, separate from its source and thumbnail. Saved output can be viewed without re-executing the model.

A drawing-level job, invoked through the CLI or MCP, receives a drawing snapshot and can inspect or patch the document. Reading the drawing and emitting an output do not themselves modify it: call update_drawing(...) for an intended change.

Submitting and Polling Jobs

MCP run_python_code returns a jobId; waitForCompletionMs defaults to 0. Submit once and poll that ID with check_python_run_job until it completes or fails. Each polling call waits at most 20 seconds, even when a longer wait is requested. A pending response is not a failed job: do not rerun pending code, particularly mutations. The CLI handles remote job polling for run-python and run-sql.

Import installed libraries explicitly and declare model output:

from build123d import Box
emit_output(Box(20, 10, 5), kind="parametric")

Embedded Methods and Values

InterfacePurpose
emit_output(value, kind=..., mime_type=..., filename=...)Declare the rendering root’s output. Use one output per root.
show(*objects, **options)Compatibility helper for supported CAD/IFC objects, including ocp_vscode.show. Prefer explicit emit_output for new scripts.
get_drawing()Return current .duc bytes when the job has a drawing snapshot; it is not a drawing metadata dictionary.
update_drawing(patch)Serialize and validate an intended drawing patch, then merge records by ID. Omitted records remain. Rendering and export jobs reject drawing updates.
get_external_files(*file_ids)Return a dictionary of mounted file IDs to byte payloads.
resolve_external_file(file_id)Return the mounted workspace path for a file ID.
external_filesMounted file metadata indexed by ID; entries include a workspace path.
drawing_filesDrawing file metadata supplied to the job.
FontEnum([...])Declare a font selection parameter with iteration, key access, and identifier-safe attributes.
resolve_font(family)Return a mounted font’s local TTF path for libraries requiring a filename.
duc_model.<stable-module-name>Import values and functions from another Python Model Element in this drawing.

File helpers only expose inputs mounted for the current job. Drawing snapshot helpers require that context; do not assume a standalone Model Element run receives a complete drawing file.

ducpy.parse_duc() is path-based. To inspect snapshot bytes, write them to a workspace .duc path and parse that path. Use ducpy’s installed API reference for builders and serialization, rather than assuming sandbox helper names are ducpy methods.

Fonts

FONTS = FontEnum(["Noto Sans", "Roboto"])
family = FONTS.Noto_Sans  # also FONTS["Noto Sans"] or iteration over FONTS
font_path = resolve_font(family)

The selected TTF must be mounted for the job; declaring a name does not install a font. resolve_font raises an error when that family is unavailable. build123d.Text(..., font=family) resolves the mounted TTF automatically; other libraries can use the returned path directly.

Output Contract

kindViewer/output
parametricSupported B-Rep/mesh objects or a tessellated CAD preview
ifcIFC model
dxfDXF drawing
imageRaster image bytes or a workspace image path
svgSVG markup/bytes or a workspace SVG path
pdfPDF bytes or a workspace PDF path
tableStructured table data

A logic-only parameter/helper module needs no output. Imported dependencies’ show(...) and emit_output(...) calls do not replace the root output. HTML and video are not Model Element output kinds; keep them as explicit file assets where appropriate. See the Model Element output contract for supported values and envelope details.

import io
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

force_n = 80.0
fig, ax = plt.subplots(figsize=(6, 3))
ax.plot([0, 1, 2], [0, force_n / 2, force_n])
ax.set(xlabel="Time / s", ylabel="Force / N")
output = io.BytesIO()
fig.savefig(output, format="png")
plt.close(fig)
emit_output(output.getvalue(), kind="image", mime_type="image/png", filename="force.png")

Reuse Geometry in Simulations

Keep the mechanical model in one Model Element. Import its actual solids, meshes, dimensions or functions from each study, then emit that study’s own image or table. Avoid copying the source assembly into every simulation.

Use the editor’s import completion to insert the stable module name; IDs containing punctuation use an encoded element_... name. Labels are readable aliases only when unambiguous. See Model Parameters and Model Modularization.

# In a study; replace the module name with the source model's stable name.
from duc_model.geometry import shaft, shaft_diameter

In this example the source Model Element must have the stable ID geometry and export both names. Prefer reusable definitions and values in shared modules; each consuming study owns its calculation assumptions and output.

Drawing Updates

Submit complete valid changed records with update_drawing({"elements": [...]}). The helper accepts a state dictionary, a compatible ducpy object, or valid .duc bytes. Dictionary and object inputs are serialized with embedded-code validation. Matching IDs update existing records, new IDs add records, and omitted records remain unchanged. Preserve existing IDs and memberships; do not submit the entire drawing merely to change one item. Inspect the result, then render it for visual QA.

Capability mapping

CapabilityExpected resultPython package(s)
CAD solids / STEPParametric geometry, B-Rep, STEP import/exportbuild123d, cadquery-ocp
BIM / IFCBuilding objects and propertiesifcopenshell
2D CAD / DXFLayers, blocks, entities and drawingsezdxf
Mesh generationSurface/volume mesh, B-Rep meshing, physical groupsnetgen-mesher / gmsh
Mesh conversionFEM/CFD format and field exchangemeshio
Geometry QAWatertightness, 3D manifold booleans, topology, intersectionstrimesh, manifold3d, shapely, rtree
3D simulation imagesMesh/scalar fields, slices, streamlines, PNG screenshotspyvista
Interactive simulation viewsStandalone HTML assets; Model viewers do not execute HTMLplotly
Simulation animationsRendered frame sequences; GIF and MP4 through the bundled encoderimageio, imageio-ffmpeg
Point-cloud registrationDenoise, align and compare scansopen3d, laspy
GIS / site dataVector queries, coordinate systemsgeopandas, pyproj
Terrain rastersDEM and geospatial raster I/Orasterio
Section propertiesArea, inertia, torsion, warping, plastic modulisectionproperties
Frame / truss / plate FEAMember forces, reactions, deflection, P–Delta, tension/compression-onlyPyNiteFEA
Structural modes / linear bucklingGeneralized eigenmodes and linearized stabilityscikit-fem, scipy
Geotechnical springsIdealized Winkler foundation, mat subgrade and nodal spring responsePyNiteFEA, scipy
Multibody dynamics / flexible contactRigid/flexible bodies, joints, collisions, nonlinear time-history integrationexudyn
Custom FEM / 3D linear elasticityWeak forms, 3D linear stress and modal prototypesscikit-fem
Nonlinear 3D solid mechanics (prototype)Large deformations, hyperelasticity, automatic differentiation, continuationfelupe, scikit-fem
Sparse PDE linear systemsKrylov solvers, sparse assembly and multigrid preconditioningscipy, pyamg
Optimized numerical kernelsJIT-compile custom CPU numerical loopsnumba, numpy
Fatigue screeningRainflow cycles, S–N life, cumulative damagepylife, rainflow
Structural criterion checksEvaluate engineer-approved allowablesnumpy, pint
Topology prototypesExplore candidate layouts, not final designsscikit-fem, pymoo
Pipe / duct sizingPressure drops, friction, flow correlationsfluids, scipy
Incompressible CFD2D/3D Navier—Stokes, velocity and pressure fieldsphiflow
Lattice Boltzmann CFD1D/2D/3D numerical flow simulationspylbm
CFD-to-heat prototypeScript fluid boundary fields into solid heat PDEphiflow, FiPy
Heat exchangersHeat-transfer correlations and sizinght, fluids
Fluid propertiesEnthalpy, density, phase propertiesCoolProp, thermo
Refrigeration / heat pumpsRefrigerant cycle and state calculationsCoolProp, ht
Ground-source heat pumpsBorehole field thermal responsepygfunction
PsychrometricsDew point, humidity, moist-air enthalpypsychrolib, CoolProp
Transient heat / transport PDEFinite-volume diffusion, advection and reaction termsFiPy
Reaction kinetics / combustionChemical equilibrium, species, reactorscantera
Smoke tracer prototypeAdvection—diffusion of prescribed species (not fire CFD)FiPy
Room acousticsReverberation, impulse responsespyroomacoustics
Water networksPipe flow, pressure and network qualitywntr
Stormwater / sewer hydraulicsRainfall, runoff, routing and sewer flowspyswmm, swmm-toolkit
Groundwater time-seriesSimulate and calibrate groundwater heads over timepastas
Groundwater PDE (prototype)Script Darcy flow with prescribed hydraulic coefficientsscikit-fem, scipy
Flood modelling (2D)Shallow-water overland depth, velocity, extentlandlab ; anuga is an excluded optional extra
Bridge scour screeningCalculate approved empirical envelopesnumpy, scipy
Solar PVIrradiance and photovoltaic yieldpvlib
Solar shadow screeningSolar positions and ray/geometry intersectionpvlib, trimesh, manifold3d
Daylight simulationRay-traced illuminance, daylight factor and glare metricspyradiance
Simple building thermal modelScripted thermal RC-network energy balancesscipy, control
Whole-building energy simulationDynamic multizone building energy and HVAC simulationpyenergyplus-lbnl
Battery simulationCell electrochemistry, charge/discharge and aging modelspybamm
RF / microwave networksS-parameters, signal-chain and transmission-line analysisscikit-rf
Electromagnetic fields (prototype)3D Maxwell FDTD wave propagationfdtd
Electrical power flowAC/DC networks and faultspandapower
Energy-grid optimizationGeneration, storage, LP/MILP dispatch studiespypsa, highspy
ControlsState space, stability and responsecontrol, scipy
Sensor analysisFilter, align and assess time seriespandas, scipy
SensitivitySobol, Morris and input influenceSALib
Uncertainty / reliabilityUncertainty propagation and reliabilityopenturns
Constrained optimizationLP/MILP/QP/conic solvers and multiobjective Pareto searchscipy, highspy, clarabel, pymoo
Multidisciplinary optimizationCoupled models and derivativesopenmdao
One-way fluid-to-structure prototypeApply computed fluid loads to scripted elastic modelphiflow, scikit-fem
Manufacturability screeningOffsets, thickness and manifold geometry checksbuild123d, trimesh, manifold3d
Scan-based inspectionCompare measured cloud with modelopen3d, laspy
Units / dimensionsConvert quantities, detect unit errorspint
Basis / evidence schemaImplement typed records and validationpydantic
T0–T3 scoringImplement evidence levels and dependency capspydantic, networkx
Content-addressed evidenceCanonical JSON and cryptographic hashesrfc8785 (plus stdlib hashlib)
ProvenanceTrace sources, calculations and dependenciesprov, networkx
Portable evidence packagesExport interoperable research recordsrocrate
Digital signaturesSign and verify evidence payloadscryptography
Reproducible workflowsExecute analysis DAGs and rerunssnakemake
Verification testsBenchmarks, property tests and regressionspytest, hypothesis, pytest-benchmark
Engineering reports / 2D plotsGraphs, heatmaps, PDF, DOCX and spreadsheetsmatplotlib, typst, python-docx, openpyxl

This is a capability map for the declared library families, not a claim that every workflow is a turnkey solver. The project includes these families in the shared base environment. ANUGA (flood-gpl) is optional and excluded from both standard desktop and server profiles. Consult the selected package’s own license and API when preparing a worker or distributing results.

Visual Results and Runtime Limits

Use Matplotlib with Agg for PNG/SVG charts, and PyVista for off-screen mesh/field screenshots. Plotly can generate standalone HTML; Kaleido static export requires Chrome/Chromium, which is not a dependency of this Python profile.

Jobs run in worker processes with network, subprocess and sensitive-host-path guards. The process adapter permits the locked environment’s bundled FFmpeg, Radiance and EnergyPlus executables; arbitrary shell commands, Python child processes and network sockets remain blocked. Snakemake workflows that launch arbitrary external commands require a separate worker. Use from Pynite import FEModel3D for PyNiteFEA and import phi for PhiFlow; their distribution names differ from their import names.

Headless Linux images also need the native shared libraries required by their wheels, including OpenGL/X11 and OpenMP where applicable. Open3D’s Linux wheels require a sufficiently new glibc. Large native stacks belong in container-backed workers rather than ordinary Lambda zip deployments. These constraints are part of deployment verification, not capabilities Python dependencies alone can guarantee.

The numerical libraries enable custom finite-element, finite-volume, CFD, thermal and optimization workflows. They do not supply a validated general industrial turbulence, plasticity/contact, aquifer, fire or two-way fluid/structure solver. Define inputs, units, mesh, boundary conditions and numerical methods explicitly; check convergence and benchmark results before using them for engineering decisions. Library availability indicates computability, not physical validation, standards compliance or an authorized design release.

Last updated on