You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Purpose

The LM-X Python wrapper is a thin Python interface over the native LM-X client library. It provides Pythonic access to the whole LM-X API.

Package Contents

The wheel contains:

  • Python package: lmx (client.py, _ffi.py, _marshal.py, _callbacks.py, types.py, errors.py)
  • Embedded native LM-X client library (platform-specific):
    • liblmx.so (Linux/Unix)
    • liblmx.dylib (macOS)
    • liblmx.dll (Windows)

The wheel is non-pure (root_is_pure = False) and platform-tagged.

Prerequisites

  • Python >= 3.8
  • LM-X SDK build output for your target platform
  • Matching Python bitness and SDK target bitness (32-bit vs 64-bit)

Build the Wheel

Recommended (from SDK root)

Build the SDK as usual; wheel build is part of the SDK makefile flow:

  • Unix-like:
    make
    
  • Windows (Visual Studio + nmake environment):
    nmake
    

This runs python/build_sdk_wheel.py and produces:

  • python/lmx-*.whl
  • python/wheel_build.log

Build only the wheel target

  • Unix-like:
    make build_python_wheel
    
  • Windows:
    nmake build_python_wheel
    

Manual script invocation

From SDK root:

python3 python/build_sdk_wheel.py \
  --platform linux_x64 \
  --library linux_x64/liblmx.so \
  --output-dir python \
  --venv python/.venv_wheel

Notes:

  • --platform must match LM-X host directory naming (for example linux_x64, win64_x64, darwin_universal).
  • The script skips build (exit code 0) when prerequisites are not met and logs SKIPPED: reason to python/wheel_build.log.

Install and Start

Install the generated wheel

From SDK examples/python:

pip install ../../python/lmx-*.whl

Run example scripts

python3 local.py
python3 network.py
python3 callbacks.py
python3 licstat.py
python3 clientstore.py
python3 trial.py
python3 admin.py

You can also use the provided example makefile targets:

  • Unix: make run_local (and run_network, run_callbacks, run_licstat, run_clientstore, run_trial, run_admin, run_all)
  • Windows: nmake run_local (same target set)

Minimal Usage Example

from lmx import LMX_STATUS, LmxClient, LmxSettings

FEATURE = "f2"

with LmxClient() as client:
    status = client.init()
    if status != int(LMX_STATUS.LMX_SUCCESS):
        raise RuntimeError(f"LMX_Init failed: {status}")

    # Setup license path
    client.set_option(LmxSettings.LMX_OPT_LICENSE_PATH, "6200@localhost")

    # Checkout one license
    status = client.checkout(FEATURE, 1, 0, 1)
    if status != int(LMX_STATUS.LMX_SUCCESS):
        error = client.get_error_message()
        raise RuntimeError(f"LMX_Checkout failed: status={status}, error={error}")

    # Checkin the license
    status = client.checkin(FEATURE, 1)
    if status != int(LMX_STATUS.LMX_SUCCESS):
        raise RuntimeError(f"LMX_Checkin failed: {client.get_error_message()}")

How It Works

  1. LmxClient is a thread-safe OO facade over LM-X C APIs.
  2. The wrapper loads native LM-X symbols through ctypes.CDLL (lmx/_ffi.py).
  3. Method calls map 1:1 to native exports (LMX_Init, LMX_Checkout, LMX_Checkin, etc.).
  4. Complex C structs are converted into Python dictionaries/dataclasses by marshal helpers (lmx/_marshal.py).
  5. Python callback options are converted to C function pointers.
  6. Status codes are returned as integers compatible with LMX_STATUS enum values.

Native Library Resolution Order

When creating LmxClient() without explicit library_path, the wrapper searches in this order:

  1. Explicit constructor path (library_path) - must be absolute.
  2. LMX_PYTHON_LIBRARY_PATH env var (absolute file path or absolute directory).
  3. Directory containing lmx/_ffi.py (typically wheel package location).
  4. Current working directory.
  5. OS PATH entries.

If no valid library is found, LmxUsageError is raised with attempted paths.

Troubleshooting

Wheel not generated

Symptoms:

  • No python/lmx-*.whl after build

Checks:

  1. Inspect python/wheel_build.log for SKIPPED: messages.
  2. Verify Python interpreter exists and is callable.
  3. Verify interpreter bitness matches target platform bitness.
  4. Verify native library path provided to build script exists.

Could not locate LM-X client library

Symptoms:

  • Import/initialization fails with path-resolution error

Checks:

  1. Ensure wheel was installed successfully (pip show lmx).
  2. If overriding library location, set absolute LMX_PYTHON_LIBRARY_PATH.
  3. If using LmxClient(library_path=...), pass an absolute file path.
  4. Confirm file name matches platform (.so, .dylib, .dll).

Callback-related crashes or unexpected behavior

Checks:

  1. Register callbacks via set_option() only.
  2. Keep callback signatures compatible with expected LM-X callback shapes.
  3. Do not bypass LmxClient internals for callback pointer handling.
  • No labels