Back to API Reference

Python API

Overview

The Python API provides a ctypes-based wrapper around the GCode shared library. It exposes a Pythonic interface with context manager support, exception-based error handling, and dict-like result objects.

from gcode_api import GCode, GCodeError, ErrorCode, ResultType, GCodeResult

Getting Started

Prerequisite: Galil GCLIB must be installed on the target machine before using this library. Download it from galil.com.

1. Install

Requires Python 3.10 or later. Install the package with pip:

pip install https://www.galil.com/sw/pub/win/galil_gcode-1.2.1-py3-none-win_amd64.whl

To upgrade to a newer release, run the same command with --upgrade: pip install --upgrade <url>.

Note: the package you install is galil-gcode, but the module you import is gcode_api — i.e. import gcode_api, not import galil_gcode.

2. Verify

Confirm the package is installed and the library loads:

python -c "from gcode_api import GCode; print('OK')"

3. Set License Key

GCode() reads your license key from the GCODE_LICENSE_KEY environment variable. Set it once, permanently:

setx GCODE_LICENSE_KEY "your-license-key-here"

Important: setx does not update the current terminal session. You must close and reopen your Command Prompt (or PowerShell) before the variable will be visible. Alternatively, pass the key explicitly: GCode("your-license-key-here").

4. Quick Example

Connect to a controller, configure two axes, and execute a move:

from gcode_api import GCode

# License key is read from the GCODE_LICENSE_KEY environment variable
with GCode() as gcode:
    gcode.connect("192.168.1.100")

    gcode.configure_linear_axis("X", "A", counts_per_unit=1000.0)
    gcode.configure_linear_axis("Y", "B", counts_per_unit=1000.0)

    gcode.add_command("G1 X10 Y10 F100")
    gcode.start()
    gcode.wait_for_queue_empty()

5. Bundled Examples

The package ships with a tkinter GUI example and a sample G-code file. Run the GUI example directly:

python -m gcode_api.examples.gui_example

To find the example source files on disk (for reading or copying):

python -c "from gcode_api import examples; print(examples.__path__[0])"

ErrorCode

class ErrorCode(IntEnum)

Integer enum of all error codes returned by the underlying C library. When the Python API raises a GCodeError, its error_code attribute is an ErrorCode member.

MemberValueDescription
OK0Success
INVALID_HANDLE1Handle has been destroyed or is invalid
NOT_CONNECTED2Not connected to a controller
ALREADY_CONNECTED3Already connected
CONNECTION_FAILED4Connection attempt failed
PARSE_FAILED5G-code string could not be parsed
FILE_NOT_FOUND6File path does not exist
FILE_READ_ERROR7File could not be read
INVALID_ARGUMENT8Invalid argument provided
PROCESSING_ACTIVE9Cannot modify configuration while processing
TIMEOUT11Operation timed out
LICENSE12License error
NOT_FOUND13Key not found in result
TYPE_MISMATCH14Result key exists but has a different type
UNKNOWN99Unclassified error

ResultType

class ResultType(IntEnum)

Identifies the kind of data carried by a GCodeResult.

MemberValueDescription
NONE0No result data
POSITION1Axis position data (e.g., from M114)
MESSAGE2Text message (e.g., from M118)

GCodeError

class GCodeError(Exception)

Raised when any GCode API call fails. All methods on the GCode class raise this exception instead of returning error codes.

Attributes

  • error_codeErrorCode enum member indicating the failure reason
  • message — Human-readable error description from the C library, or a default derived from the error code name

Example

from gcode_api import GCode, GCodeError, ErrorCode

with GCode("your-license-key-here") as gcode:
    try:
        gcode.connect("192.168.1.100")
    except GCodeError as e:
        if e.error_code == ErrorCode.CONNECTION_FAILED:
            print(f"Could not reach controller: {e.message}")
        else:
            raise

GCodeResult

class GCodeResult

Result data returned by a command (e.g., position data from M114, a message from M118). Passed to the set_on_command_result callback. The object is safe to store and use after the callback returns.

Properties

PropertyTypeDescription
typeResultTypeThe kind of result data

Typed Accessors

MethodReturnsDescription
get_double(key)Optional[float]Numeric value or None
get_int(key)Optional[int]Integer value or None
get_string(key)Optional[str]String value or None

Dict-like Access

GCodeResult also supports standard dict operations for convenience:

result['X']          # KeyError if missing
result.get('X')      # None if missing
result.get('X', 0.0) # default if missing
'X' in result        # membership test
len(result)          # number of fields
dict(result)         # convert to plain dict

GCode

class GCode

Main entry point for the Python API. Wraps the shared library and manages the underlying handle. Supports context-manager usage for automatic cleanup.

with GCode("your-license-key-here") as gcode:
    gcode.connect("192.168.1.100")
    # ...

Optional: Set GCODE_API_LIB_PATH to override the path to the shared library. This is not required when installed via pip.

Lifecycle

GCode(license_key=None)

gcode = GCode()  # reads GCODE_LICENSE_KEY
gcode = GCode("your-license-key-here")

Creates a new GCode instance and loads the shared library (on first call). If license_key is omitted, the GCODE_LICENSE_KEY environment variable is used. Raises GCodeError if no license key is available, the library cannot be loaded, the license key is invalid or expired, or the instance cannot be created.

Parameters:

  • license_key (Optional[str]) — Your license key string (provided by Galil). Defaults to the GCODE_LICENSE_KEY environment variable.

close()

gcode.close() -> None

Releases all resources. Called automatically when exiting a with block. Safe to call multiple times.

Connection Methods

connect()

gcode.connect(ip_address: str) -> None

Connects to a Galil motion controller at the specified IP address.

Parameters:

  • ip_address — IP address of the controller (e.g., "192.168.1.100")

Raises:

  • GCodeError(ALREADY_CONNECTED) — if already connected
  • GCodeError(CONNECTION_FAILED) — if connection fails

disconnect()

gcode.disconnect() -> None

Disconnects from the controller.

is_connected()

gcode.is_connected() -> bool

Returns True if connected to a controller, False otherwise.

Command Methods

add_command()

gcode.add_command(gcode_string: str) -> None

Adds a single G-code command to the execution queue.

Parameters:

  • gcode_string — G-code command (e.g., "G1 X10 Y20 F100")

Raises:

  • GCodeError(PARSE_FAILED) — if the command cannot be parsed

add_file()

gcode.add_file(file_path: str | os.PathLike) -> None

Loads and queues all G-code commands from a file. Accepts both strings and pathlib.Path objects.

Raises:

  • GCodeError(FILE_NOT_FOUND) — if the file does not exist
  • GCodeError(FILE_READ_ERROR) — if the file cannot be read
  • GCodeError(PARSE_FAILED) — if a command cannot be parsed

get_queue_size()

gcode.get_queue_size() -> int

Returns the number of commands currently in the queue.

clear_queue()

gcode.clear_queue() -> None

Removes all pending commands from the queue. Does not affect the currently executing command.

Execution Methods

start()

gcode.start() -> None

Starts or resumes processing the command queue on a background thread. Idempotent: calling when already running is a no-op. If paused (M0/M1 or error), resumes from where it left off.

Raises:

  • GCodeError(NOT_CONNECTED) — if not connected

stop()

gcode.stop() -> None

Stops processing. The current command completes before stopping. Call start() to resume.

wait_for_queue_empty()

gcode.wait_for_queue_empty(timeout_ms: int = -1) -> None

Blocks until all queued commands have been processed.

Parameters:

  • timeout_ms — Maximum wait in milliseconds, or -1 for infinite (default)

Raises:

  • GCodeError(TIMEOUT) — if the timeout expires
  • GCodeError(NOT_CONNECTED) — if not connected

Configuration Methods

Configuration methods must be called when the processor is not actively running. Calling them during processing raises GCodeError(PROCESSING_ACTIVE).

configure_linear_axis()

gcode.configure_linear_axis(
    gcode_axis: str,
    dmc_axis: str,
    counts_per_unit: float,
    forward_limit: float = float("inf"),
) -> None

Maps a G-code axis letter to a physical DMC controller axis.

Parameters:

  • gcode_axis — G-code axis letter ("X", "Y", "Z", etc.)
  • dmc_axis — DMC axis letter ("A" through "H")
  • counts_per_unit — Encoder counts per user unit (e.g., counts per mm)
  • forward_limit — Maximum travel in user units. Defaults to no limit.

Raises:

  • GCodeError(INVALID_ARGUMENT) — if axis letters are invalid
  • GCodeError(PROCESSING_ACTIVE) — if called while processing

configure_spindle()

gcode.configure_spindle(
    dmc_axis: str,
    counts_per_revolution: float,
) -> None

Configures the DMC axis that controls the spindle.

Parameters:

  • dmc_axis — DMC axis letter ("A" through "H")
  • counts_per_revolution — Encoder counts per spindle revolution

configure_extruder()

gcode.configure_extruder(
    dmc_axis: str,
    counts_per_unit: float,
) -> None

Configures the DMC axis that controls the extruder.

Parameters:

  • dmc_axis — DMC axis letter ("A" through "H")
  • counts_per_unit — Encoder counts per user unit

Logging

enable_logging()

gcode.enable_logging(file_path: str | os.PathLike) -> None

Enables logging to the specified file. Accepts both strings and pathlib.Path objects.

Callbacks

Threading: All callbacks except set_on_started are invoked on a worker thread. Keep callback code simple and thread-safe. Consider using a queue.Queue to pass data to the main thread.

set_on_error()

gcode.set_on_error(
    callback: Optional[Callable[[ErrorCode, str, str], None]]
) -> None

Sets a callback for errors during command execution. Pass None to clear.

Callback signature:

def on_error(error_code: ErrorCode, command: str, message: str) -> None
  • error_codeErrorCode indicating the failure
  • command — The G-code string that caused the error
  • message — Human-readable error description

set_on_command_result()

gcode.set_on_command_result(
    callback: Optional[Callable[[str, GCodeResult], None]]
) -> None

Sets a callback for when a command produces result data (e.g., M114, M118). Pass None to clear. The GCodeResult object is safe to store and use after the callback returns.

Callback signature:

def on_result(command: str, result: GCodeResult) -> None

set_on_stopped()

gcode.set_on_stopped(
    callback: Optional[Callable[[], None]]
) -> None

Sets a callback for when processing stops (M0/M1 pause, error, or explicit stop() call). Pass None to clear.

set_on_started()

gcode.set_on_started(
    callback: Optional[Callable[[], None]]
) -> None

Sets a callback for when processing starts or resumes. Unlike the other callbacks, this one is called on the caller's thread. Pass None to clear.