Python client for the Goals ARM model. Uses the model calculation engine from the GoalsARM repository.
Clone the repo, and install it via uv
uv buildFor development, you'll need to install
- Boost (>=1.8.2, <=1.8.5) installed. The easiest way I find to do this, on windows, is to install one of the prebuilt binaries linked from the download page.
- uv which is used to manage the project
- CMake (>=3.15) for compiling the C++ code
- Python (>=3.10), you can use uv to install this. You'll need development headers to compile the C++ code.
Note that when you run a uv command for the first time the C++ code will be compiled. But you will have to re-compile manually to pull in any changes. The python code will be installed in development mode, so any changes you make will be picked up automatically. But any changes to the C++ code will require a manual recompilation.
We're using scikit-build-core for compiling the C++ code. This uses CMake to compile and should manage fetching any C++ dependencies (boost, GoalsARM source) and building the Python bindings.
To create the venv
uv syncThen to activate it, on Windows via command prompt or powershell
.venv\Scripts\activateor on Linux
source .venv/bin/activateNote that first time you use a uv command it will compile the C++ code for you, but you will need to manually recompile if you make any changes to the C++ code. You can do this by passing --reinstall arg to any command. For example
uv sync --reinstallor
uv run --reinstall pytestor just the current pacakge
uv run --reinstall-package goals pytestBy default, the C++ code will be compiled in release mode (with optimisations) and using GoalsARM from GitHub.
You can pass args to compile in debug mode
DEBUG_BUILD=true uv run --reinstall-package goals pytestor
uv run scripts/compile.py --debugor against local sources
LOCAL_BUILD=true uv run --reinstall-package goals pytestor
uv run scripts/compile.py --localYou will need to set the path to your local sources by changing GOALS_ARM_PATH in pyproject.toml. You need to use a fully qualified path for this.
Note that when compiling against non-local sources, CMake will fetch the main branch of GoalsARM from GitHub. You can configure this by changing GOALS_ARM_GIT_TAG in pyproject.toml.
These can be combined e.g.
uv run scripts/compile.py --debug --localNote that any changes to the Python code will be picked up automatically, but you will need to recompile the C++ code manually if there are any changes. You can do this with the --reinstall or --reinstall-package goals flags.
uv run pytestYou'll need to run these from within the uv.
uv run ./scripts/calibrate.py
uv run ./scripts/simulate.pyRun tests analysing code coverage.
uv run pytest --cov --cov-config=pyproject.tomlThis will use ruff. Configure settings in pyproject.toml
uvx ruff checkTo automatically format the code
uvx ruff format- Install the Python extension from Microsoft
If you are only developing the Python code, this is fairly straightforward.
- Open the folder in VSCode
- Create the virtual environment with
uv, from a terminal in VSCode runuv sync. This will create a virtual environment.venv, install dependencies and compile the C++ code. - You now need to point VSCode to the Python interpreter managed by
uv, there are two ways- Open the command palette (Ctrl+Shift+P) and run "Python: Select Interpreter" to the version of Python from your virtual env. It should be something like
.venv/bin/pythonor.venv\Scripts\pythonon Windows. You may need to restart VSCode after creating the venv in step 2. - or, open the command palette (Ctrl+Shift+P) and run "Python: Create Environment", select "Venv" type, then select "GoalsARMPython". Note that this should be the existing venv, you should not recreate the environment afresh.
- Open the command palette (Ctrl+Shift+P) and run "Python: Select Interpreter" to the version of Python from your virtual env. It should be something like
- You should now be able to run and debug the Python tests and code from the IDE. Changes to Python code will be picked up automatically, but note that if you want to update any of the C++ you will need to recompile. To do so run
uv sync --reinstalloruv sync --reinstall-package goalsfrom the terminal. - This will pull and install GoalsARM C++ code from GitHub. You can change the branch if you want by setting
GOALS_ARM_GIT_TAGinpyproject.tomland recompiling viauv sync --reinstall
Note that as this file contains a CMakeLists.txt your IDE might try and interpret this project as a CMake project. This will not compile as a raw CMake project, it requires scikit-build-core to compile succesfully. If you are using the CMake Tools VSCode extension, you can stop this by adding the following to your .vscode/settings.json.
{
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.autoSelectActiveFolder": false,
"cmake.sourceDirectory": "",
"cmake.ignoreCMakeListsMissing": true
}
If you want to debug your a local copy of GoalsARM C++ code we need to do some more setup.
- Install the Python & C++ Debugger extension
- Add the GoalsARM package to this VSCode workspace "File" -> "Add folder to Workspace..."/ (note that this won't work if you open GoalsARM and add GoalsARMPython to the workspace. You must open GoalsARMPython first)
- If you don't already have one, create a
launch.jsonby following the steps here - On Windows, add the following configuration to your
.vscode/launch.jsonOn Linux, swap the "cppConfig" for "default (gdb) Attach".{ "version": "0.2.0", "configurations": [ { "name": "Python C++ Debugger", "type": "pythoncpp", "request": "launch", "pythonConfig": "default", "cppConfig": "default (win) Attach" }, ] } - Set the path to the root of your local checkout of GoalsARM by setting the value of
GOALS_ARM_PATHin thepyproject.toml - Recompile the code for debugging,
uv run scripts/compile.py --debug --local. This will compile with debug symbols and link it to your local copy. - You should now be able to set breakpoints, in any of the GoalsARMPython code or the GoalsARM code.
- To run it, open the "Run and debug" tab in VSCode, open the file you want to debug. Check the "Python C++ Debugger" is selected at the top and click the play button to start the debugger. This will launch a Python debugger and a C++ debugger and attach to it using the process ID of the Python debugger.
To have the Python and C++ debugger work from tests requires more configuration. By default the Python extension makes the test runner and test debug available to you. If you only want to debug the Python code, this will work fine. If you want to debug the C++ code also, this is not possible at the moment with the Python & C++ debugger extension. Easest way to achieve this is create a temporary file in scripts which calls your test e.g.
import pytest
if __name__ == "__main__":
pytest.main()You can pass args to pytest.main to run a single file e.g. to run just "tests/test_goals_excel.py", call pytest.main(["tests/test_goals_excel.py"]). Then run this via "Run and Debug` described in the section above.