Skip to main content

Python library for the SolidCAM Automation COM API

Project description

solidcam-api

A fully-typed Python library for the SolidCAM Automation COM API (scautom.dll).

solidcam-api wraps every section of the SolidCAM Automation API — General, CAD, CAM, Machine, Part, Operation, Tool, Geometry, and Templates — in a clean, Pythonic interface with:

  • Full type annotations and a py.typed marker (PEP 561)
  • Frozen dataclasses for all result objects
  • IntEnum constants for all integer codes
  • A context-manager-friendly client
  • Dependency injection / mock support for unit testing without SolidCAM

Platform note — SolidCAM is a Windows application.
The COM layer is only active on Windows; the package can be imported on any OS for documentation builds, static analysis, and testing with mocks.


Table of Contents


Requirements

Requirement Version
Python ≥ 3.13
pywin32 ≥ 307 (Windows only)
SolidCAM any version with scautom.dll registered

Before using the library, the SolidCAM COM server must be registered:

regsvr32 "C:\Program Files\SolidCAM\scautom.dll"

This is done automatically by the SolidCAM installer.


Installation

pip install solidcam-api

With development tools (linting, type checking, tests):

pip install "solidcam-api[dev]"

With documentation build dependencies:

pip install "solidcam-api[docs]"

Quick start

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"C:\CAM\my_part.prz")
    sc.calculate()
    sc.generate_gcode()
    sc.close()

Usage examples

Open a part and generate G-code

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    # Start host CAD (SolidWorks) — wait for plugin to initialise
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")

    # Open a CAM part (no reference-model replacement)
    sc.open(r"D:\jobs\bracket.prz")

    # Check current part info
    print(sc.part_path)       # D:\jobs\bracket.prz
    print(sc.part_type)       # PartType.MILLING
    print(sc.reference_model) # D:\cad\bracket_v3.sldprt

    # Synchronise, calculate all operations, write G-code
    sc.synchronize()
    sc.calculate()
    sc.generate_gcode()

    # Save to a delivery folder
    saved_path = sc.save(r"D:\output")
    print(f"Saved to {saved_path}")

    sc.close()

Change the reference model and recalculate

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"D:\jobs\bracket.prz")

    # Swap in the new revision of the CAD model
    sc.change_reference_model(r"D:\cad\bracket_v4.sldprt")

    sc.synchronize()
    sc.calculate()
    sc.generate_gcode()
    sc.close()

List machines, operations, and tools

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"D:\jobs\bracket.prz")

    # --- Machines ---
    print(f"Available machines ({sc.machine_count}):")
    for machine in sc.list_machines():
        print(f"  [{machine.index}] {machine.name}")

    print(f"Current machine: {sc.current_machine_name}")

    # --- Operations ---
    print(f"\nOperations ({sc.operation_count}):")
    for op in sc.list_operations():
        print(f"  [{op.index}] {op.name!r:30s}  type={op.type}")

    # Suppress a roughing pass for a quick finish-only run
    sc.suppress_operation("Roughing_1", suppress=True)

    # --- Tools ---
    print(f"\nTools ({sc.tool_count}):")
    for tool in sc.list_tools():
        print(f"  [{tool.index}] {tool.name!r:25s}  type={tool.type}")

    sc.close()

Create stock and target geometry

from solidcam_api import SolidCAMClient, StockDefineBy, TargetDefineBy

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"D:\jobs\new_part.prz")

    # Create a box stock with 2 mm offsets on every face
    sc.create_stock_box(
        name="Stock_Box",
        x_plus=2.0, x_minus=2.0,
        y_plus=2.0, y_minus=2.0,
        z_plus=2.0, z_minus=0.0,  # no offset on the bottom face
        define_by=StockDefineBy.SOLID,
        generate_stock_envelope=True,
    )

    # Create a cylindrical stock for a turning part
    sc.create_stock_cylinder(
        name="Bar_Stock",
        right=3.0,
        left=3.0,
        external_diameter=2.0,
        define_by=StockDefineBy.SOLID,
    )

    # Create a target from the finished solid
    sc.create_target(
        name="Finished_Part",
        define_by=TargetDefineBy.SOLID,
        generate_envelope=True,
    )

    # Inspect resulting geometry entries
    for geom in sc.list_geometries():
        print(geom.name)

    sc.close()

Apply a process template

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"D:\jobs\new_part.prz")

    # List available process templates
    for pt in sc.list_process_templates():
        print(pt.name)

    # Instantiate a process template against an existing geometry
    sc.create_jobs_from_process_template(
        process_template_name="Finish_Profile_Template",
        geometry_name="Finished_Part",
        sub_machine_index=1,
    )

    sc.calculate()
    sc.generate_gcode()
    sc.close()

Generate a tool sheet

from solidcam_api import SolidCAMClient

with SolidCAMClient() as sc:
    sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
    sc.open(r"D:\jobs\bracket.prz")

    # Discover available templates
    print(sc.list_tool_sheet_names())
    # e.g. ['Sheet_Full_HTML', 'Sheet_Full_RTF', ...]

    sc.generate_tool_sheet("Sheet_Full_HTML")
    sc.close()

API overview

All methods and properties are available directly on SolidCAMClient.

Connection lifecycle

Member Description
SolidCAMClient(prog_id, *, com_object) Initialise (no COM connection yet)
.connect() Create the COM dispatch object
.disconnect() Release the COM dispatch object
.is_connected True if the COM object is held
with SolidCAMClient() as sc: Preferred: auto connect/disconnect

General

Member Description
.last_error Last error code (0 = no error)
.last_error_description Human-readable last error message
.log_file Path to the API log file (get/set)
.pid Process ID of the target SolidCAM instance (get/set)
.is_solidcam_running() True if SolidCAM process is active
.start_application(path, wait_for_plugin) Start SolidWorks or standalone SolidCAM
.start_solidcam() Start SolidCAM plugin (SolidWorks must be running)

CAD

Member Description
.open_host_file(path) Open a CAD file in the host
.is_active_doc_cam_part True if the active document is a CAM part
.render_preview(path) Generate a PDM preview image

CAM

Member Description
.open(part_path, model_path) Open a CAM part; optionally replace reference model
.check_synchronization() Check sync status
.synchronize() Synchronise the CAM part with its reference model
.calculate(only_not_calculated) Calculate all (or only outdated) operations
.calculate_operations(operations, only_not_calculated) Calculate a list of named operations
.calculate_single_operation(number) Calculate one operation by number
.change_post_processor_directory(path) Change the post-processor directory
.generate_gcode() Generate G-code for the entire part
.save(folder) Save to folder; returns the saved file path
.save_as(path) Save to a new file path
.save_to_folder(folder) Save to folder; returns the saved file path
.close() Close the currently open CAM part
.exit() Close SolidCAM entirely

Machine

Member Description
.machine_count Number of available machines
.current_machine Index of the active machine (get/set)
.current_machine_name Name of the active machine
.get_machine_name(index) Name of machine at index
.list_machines() list[Machine] of all machines

Part

Member Description
.part_path Path to the currently open CAM part
.part_type PartType of the open part
.reference_model Path to the reference CAD model
.change_reference_model(model_path) Replace the reference model
.create_new_part(name, path, part_type, machine_index, home_origin_position, inch) Create a new CAM part

Operation

Member Description
.operation_count Number of NC operations
.number_of_jobs_with_exclamation_sign Count of operations with warnings
.get_operation_name(index) Name of operation at index
.get_operation_type(index) Raw type code of operation at index
.get_operation(index) Operation dataclass at index
.list_operations() list[Operation] of all operations
.suppress_operation(name, suppress) Suppress or unsuppress a named operation
.generate_gcode_for_operation(name, file_name) G-code for one operation

Tool

Member Description
.tool_count Number of tools in the tool table
.tool_sheet_count Number of tool-sheet templates
.get_tool_name(index) Name of tool at index
.get_tool_type(index) Raw type code of tool at index
.get_tool_tag(number, position, station, turret) Unique tool tag by address
.get_tool(index) Tool dataclass at index
.list_tools() list[Tool] of all tools
.set_operation_tool(operation_name, tool_tag) Assign a tool to an operation
.get_operation_tool_tag(operation_name) Tag of the tool used by an operation
.get_tool_sheet_name(index) Name of tool-sheet template at index
.list_tool_sheet_names() list[str] of all template names
.generate_tool_sheet(template_name) Generate a tool sheet

Geometry

Member Description
.cad_coord_sys_count Number of CAD coordinate systems
.get_cad_coord_sys_name(index) Name of CAD coord sys at index
.get_cad_coord_sys(index) CoordSys at index
.list_cad_coord_sys() list[CoordSys]
.home_count Number of home positions
.get_home_name(index) Name of home at index
.get_home(index) HomeEntry at index
.list_home_positions() list[HomeEntry]
.create_home(home_origin_position) Create a home at a given origin
.create_home_by_cad(cad_home_name) Create a home from a CAD coord sys
.geom_count Number of geometry entries
.get_geom_name(index) Name of geometry entry at index
.get_geom(index) GeomEntry at index
.list_geometries() list[GeomEntry]
.create_target(...) Create a target solid geometry
.create_stock_box(...) Create a box stock geometry
.create_stock_cylinder(...) Create a cylindrical stock geometry

Templates

Member Description
.template_count Number of operation templates
.get_template_name(index) Name of template at index
.get_template(index) TemplateEntry at index
.list_templates() list[TemplateEntry]
.create_job_from_template(name, geometry, sub_machine, index) Instantiate one operation
.process_template_count Number of process templates
.get_process_template_name(index) Name of process template at index
.get_process_template(index) ProcessTemplateEntry at index
.list_process_templates() list[ProcessTemplateEntry]
.create_jobs_from_process_template(name, geometry, sub_machine, index) Instantiate all operations

Error handling

All API methods raise SolidCAMAPIError on failure. The exception carries three attributes: method (the API call that failed), code (the integer error code from LastError), and description (the human-readable description from LastErrorDescription).

from solidcam_api import SolidCAMClient, SolidCAMAPIError, SolidCAMConnectionError

try:
    with SolidCAMClient() as sc:
        sc.start_application(r"C:\Program Files\SolidWorks\SLDWORKS.exe")
        sc.open(r"D:\jobs\bracket.prz")
        sc.calculate()
        sc.generate_gcode()
        sc.close()
except SolidCAMConnectionError as exc:
    print(f"Could not connect to SolidCAM: {exc}")
except SolidCAMAPIError as exc:
    print(f"API call '{exc.method}' failed (code {exc.code}): {exc.description}")

Exception hierarchy

SolidCAMError
├── SolidCAMConnectionError   # COM object could not be created
├── SolidCAMNotRunningError   # SolidCAM process not detected
├── SolidCAMNotOpenError      # No CAM part is currently open
└── SolidCAMAPIError          # A specific API call returned failure
      .method  – str
      .code    – int
      .description – str

Testing without SolidCAM

SolidCAMClient accepts a com_object keyword argument so you can inject a mock and test automation scripts without a SolidCAM installation.

import unittest.mock as mock
from solidcam_api import SolidCAMClient, PartType

def test_calculate_called_after_open():
    fake_com = mock.MagicMock()
    fake_com.LastError = 0
    fake_com.Open.return_value = 1
    fake_com.Type = int(PartType.MILLING)

    sc = SolidCAMClient(com_object=fake_com)
    assert sc.is_connected

    sc.open(r"C:\parts\test.prz")
    sc.calculate()

    fake_com.Open.assert_called_once_with(r"C:\parts\test.prz", "")
    fake_com.Calculate.assert_called_once_with(False)

Contributing

  1. Fork the repository and create a feature branch.
  2. Install development dependencies:
    pip install -e ".[dev]"
    
  3. Make your changes and add tests under tests/.
  4. Lint and format:
    ruff check src tests
    ruff format src tests
    
  5. Type-check:
    mypy src
    
  6. Run tests:
    pytest --cov=solidcam_api --cov-report=term-missing
    
  7. Open a pull request describing the change.

Project structure

solidcam-api/
├── src/
│   └── solidcam_api/
│       ├── __init__.py          # Public API surface
│       ├── py.typed             # PEP 561 marker
│       ├── _com.py              # Internal COM wrapper (win32com)
│       ├── client.py            # SolidCAMClient — assembles all sections
│       ├── exceptions.py        # Exception hierarchy
│       ├── enums.py             # IntEnum constants (PartType, OperationType, …)
│       ├── models/              # Frozen dataclasses for result objects
│       │   ├── machine.py
│       │   ├── operation.py
│       │   ├── tool.py
│       │   ├── geometry.py
│       │   └── template.py
│       └── sections/            # Section mixins (one per API section)
│           ├── _base.py
│           ├── general.py
│           ├── cad.py
│           ├── cam.py
│           ├── machine.py
│           ├── part.py
│           ├── operation.py
│           ├── tool.py
│           ├── geometry.py
│           └── template.py
├── tests/
├── pyproject.toml
└── README.md

License

MIT © 0ndrec

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solidcam_api-0.1.0.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solidcam_api-0.1.0-py3-none-any.whl (37.5 kB view details)

Uploaded Python 3

File details

Details for the file solidcam_api-0.1.0.tar.gz.

File metadata

  • Download URL: solidcam_api-0.1.0.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for solidcam_api-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5332133a043d24a7326176ec78775978061cb3319b5445d26963b9834294b2c8
MD5 9de64964910d1f2420f9c7ba7890ca64
BLAKE2b-256 9165ff8857218e23583738393874c04f8a5877cf325078583c05ec6c5b2a2719

See more details on using hashes here.

File details

Details for the file solidcam_api-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: solidcam_api-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for solidcam_api-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac3e60ecc9ba44ba543816f55cde500c8e355bfd3346afea94f2c1c528a7c522
MD5 cb733e47b31a628529d7ac2e89acf788
BLAKE2b-256 d4e6421c7a521cfff2086d8ebe77cd9dc16f9ac637f11339629d00eea9bade80

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page