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 entire LM-X API.
Package Contents
Example Python code (local, network, callbacks, licstat, clientstore, trial, admin) is included in the LM-X examples subdirectory.
Usage of the Python wrapper is detailed below.
Package contents
The Python wrapper package is delivered as an LM-X wheel (lmx-*-py3-none-any.whl) that you can install with pip. 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.
| Anchor | ||||
|---|---|---|---|---|
|
Prerequisites for using the Python wrapper include:
- Python version greater than or equal to version 3Python >= 3.8
- LM-X SDK build output for your target platform
- Matching Python bitness and SDK target bitness (32-bit vs or 64-bit)
Building the wheel
Build the Wheel
Recommended (from SDK root)
Building the Python wheel is described below.
Build from SDK root (recommended method)
To build the wheel from the SDK root (recommended), build Build the SDK as usual; . The wheel build is part of the SDK makefile flow:
- Unix-likeFor Unix/Linux/macOS:
make - For Windows (Visual Studio + and nmake environment):
nmake
This runs python/build_sdk_wheel.py and produces:
python/lmx-*.whlpython/wheel_build.log
Build only the wheel target
To build only the wheel target:
- Unix-likeFor Unix/Linux/macOS:
make build_python_wheel - For Windows:
nmake build_python_wheel
...
Build using manual script invocation
From To build the wheel manually from SDK root, run the following script:
| Code Block |
|---|
python3 python/build_sdk_wheel.py \ --platform linux_x64 \ --library linux_x64/liblmx.so \ --output-dir python \ --venv python/.venv_wheel |
...
Notes:
| Note |
|---|
|
...
|
...
|
...
|
...
|
...
|
...
|
...
Installing and starting the wheel
Installing and starting the wheel is described below.
...
Install the generated wheel
From SDK examples/python, run:
pip install ../../python/lmx-*.whl
Run example scripts
You can start the wheel using one of the following example scripts.
| Code Block |
|---|
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:
- For Unix/Linux/macOS:
make run_local(andrun_network,run_callbacks,run_licstat,run_clientstore,run_trial,run_admin,run_all) - For Windows:
nmake run_local(same target set)
...
Python wrapper usage example
The following is a simple example of using the Python wrapper.
| Code Block | ||||||
|---|---|---|---|---|---|---|
| ||||||
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 the Python wrapper works
The Python wrapper works as follows:
LmxClientis a thread-safe OO facade over LM-X C APIs.- The wrapper loads native LM-X symbols through
ctypes.CDLL(lmx/_ffi.py). - Method calls map 1:1 to native exports (
LMX_Init,LMX_Checkout,LMX_Checkin, etc.). - Complex C structs are converted into Python dictionaries/dataclasses by marshal helpers (
lmx/_marshal.py). - Python callback options are converted to C function pointers.
- Status codes are returned as integers compatible with
LMX_STATUSenum values.
Native
...
library resolution order
When creating LmxClient() without explicit library_path, the the wrapper searches in this order:
- Explicit constructor path (
library_path) - , where the path must be absolute. LMX_PYTHON_LIBRARY_PATHenv var (absolute file path or absolute directory).- Directory containing
lmx/_ffi.py(typically wheel package location). - Current working directory.
- OS
PATHentries.
If no valid library is found, an LmxUsageError exception is raised with for the attempted paths.
Troubleshooting
Troubleshooting for issues using the Python wrapper are described below.
Wheel not generated
SymptomsIf the wheel is not generated, you will get the following error after the build:
No python/lmx-*.whl
...
To resolve this issue, try the followingChecks:
- Inspect
python/wheel_build.logforSKIPPED:messages. - Verify that the Python interpreter exists and is callable.
- Verify that the interpreter bitness matches target platform bitness.
- Verify that the native library path provided to build the script exists.
...
Inability to locate the LM-X client library
Symptoms:
...
If the import/initialization fails
...
because the LM-X client library path cannot be resolved, you will see the following error:
Could not locate LM-X client library
To resolve this issue, try the following:
- Ensure that the
Checks:
- Ensure wheel was installed successfully (
pip show lmx). - If overriding the library location, set absolute an absolute
LMX_PYTHON_LIBRARY_PATH. - If using
LmxClient(library_path=...), pass an absolute file path. - Confirm that the file name matches the platform (
.so,.dylib,.dll).
Callback-related crashes or unexpected behavior
ChecksIf you are experiencing callback-related crashes or other unexpected behavior, try the following:
- Register callbacks via using only
set_option()only. - Keep Ensure callback signatures are compatible with expected LM-X callback shapes.
- Do not bypass
LmxClientinternals for callback pointer handling.