Runner Usage ============ ``ATClient`` executes Acoustics Toolbox models through ``at-runner``. It does not shell out to local Fortran executables directly. Install the Python API and the pinned runner client: .. code-block:: bash python -m pip install oalib-at-py python -m pip install "at-runner @ git+https://github.com/jgebbie/at-runner.git@v0.3.0#subdirectory=client/python" Remote Runner ------------- Use remote mode when an ``at-runner`` process is already listening on a gRPC endpoint: .. code-block:: python from at_py import ATClient client = ATClient(target="localhost:50051", runner_mode="remote") result = client.kraken(file_root="pekeris", inputs={"pekeris.env": env_text}) ``inputs`` maps runner-workspace filenames to ``str`` or ``bytes``. Strings are encoded as UTF-8 before the gRPC call. Returned files are exposed as raw bytes in ``result.files``. Stand Up a Local Runner ----------------------- Use the pinned published container when Docker can pull from GHCR: .. code-block:: bash docker run --rm -p 50051:50051 \ --tmpfs /workspace:rw,noexec,nosuid,size=512m \ ghcr.io/jgebbie/at-runner:v0.3.0 Then connect to ``localhost:50051`` with ``runner_mode="remote"``. The ``--tmpfs`` mount gives each container an ephemeral runner workspace and matches the default helper used by ``ATClient`` Docker mode. If you need to build the runner image locally, use the matching public tag: .. code-block:: bash git clone --branch v0.3.0 https://github.com/jgebbie/at-runner.git cd at-runner docker build -t at-runner:v0.3.0 . docker run --rm -p 50051:50051 \ --tmpfs /workspace:rw,noexec,nosuid,size=512m \ at-runner:v0.3.0 Docker On Demand ---------------- Use Docker mode when you want ``ATClient`` to start the pinned runner image on first use: .. code-block:: python from at_py import ATClient with ATClient(runner_mode="docker", docker_host_port=50051) as client: result = client.kraken(file_root="pekeris", inputs={"pekeris.env": env_text}) Docker mode requires the ``docker`` CLI on ``PATH``. ``ATClient.close()`` stops the ephemeral container; a context manager is the easiest way to guarantee cleanup. Pinning ------- The runner stack is pinned through package runtime constants: * ``at_py.AT_RUNNER_GIT_REF`` * ``at_py.DEFAULT_AT_RUNNER_IMAGE`` * ``at_py.runner_docker.AT_RUNNER_CLIENT_REQUIREMENT`` ``tests/test_runner_pin.py`` checks that ``pyproject.toml`` metadata and runtime constants stay aligned. Integration Tests ----------------- Integration tests start the pinned Docker image, call it through the installed ``at_runner`` client, and run a minimal KRAKEN case: .. code-block:: bash python -m pip install -e ".[dev]" python -m pip install "at-runner @ git+https://github.com/jgebbie/at-runner.git@v0.3.0#subdirectory=client/python" pytest -m integration The tests skip when ``at_runner`` cannot be imported, Docker is unavailable, or the container cannot accept connections in time.