diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e61495e0fcbf5a4a299d21479891aad98e83ded..546ab758b046d2b052f5b236ef5d8831177e66dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to a versioning scheme similar to Matlab, with versions - Complete rework of binding using `betterproto` for a pure Python implementation (!4) - Set the minimum Python version to 3.9 (!9) - CMakeLists.txt adapted to new, pure Python binding (!12) +- Improved README.md (!15) ## [2023b] - 2023-11-16 diff --git a/CMakeLists.txt b/CMakeLists.txt index e7febf6eb380af8c3a95e4a835e280f1f8bab2b6..f4b56c67f4969cac2cc87a44fe10c51a3438b9bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ else () set (VAPYTHON_BUILD_COMMAND echo "hatch not found, skipping build for VAPython") endif () -add_custom_target(${PROJECT_NAME} COMMAND ${VAPYTHON_BUILD_COMMAND}) +add_custom_target(${PROJECT_NAME} COMMAND ${VAPYTHON_BUILD_COMMAND} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) set_property (TARGET ${PROJECT_NAME} PROPERTY FOLDER "Bindings/VA") @@ -25,14 +25,7 @@ set (VA_PYTHON_OUTPUT_FOLDER "VAPython_v${PROJECT_VERSION_MAJOR}${RELEASE_LETTER # Readme install ( - FILES "README.md" - DESTINATION ${VA_PYTHON_OUTPUT_FOLDER} - COMPONENT ${PROJECT_NAME} -) - -# Examples -install ( - DIRECTORY "examples" + FILES "README.md" "LICENSE.md" "CHANGELOG.md" DESTINATION ${VA_PYTHON_OUTPUT_FOLDER} COMPONENT ${PROJECT_NAME} ) @@ -41,6 +34,7 @@ install ( install (CODE "set(VA_PYTHON_OUTPUT_FOLDER \"${VA_PYTHON_OUTPUT_FOLDER}\")" COMPONENT ${PROJECT_NAME}) install (CODE "set(VA_PYTHON_PACKAGE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}\")" COMPONENT ${PROJECT_NAME}) install (CODE "set(VA_PYTHON_PACKAGE_WHEEL \"vapython-${PROJECT_VERSION}-py3-none-any.whl\")" COMPONENT ${PROJECT_NAME}) +install (CODE "set(VA_PYTHON_PACKAGE_WHEEL_FINAL \"vapython-v${PROJECT_VERSION_MAJOR}${RELEASE_LETTER}-py3-none-any.whl\")" COMPONENT ${PROJECT_NAME}) # during install create a wheel from the content of the python folder and include it in the install install ( @@ -59,12 +53,16 @@ install ( message(FATAL_ERROR "Python3 not found") endif () - file(GLOB _wheel "${VA_PYTHON_PACKAGE_PATH}/dist/${VA_PYTHON_PACKAGE_WHEEL}") - if (NOT _wheel) + set(_wheel "${VA_PYTHON_PACKAGE_PATH}/dist/${VA_PYTHON_PACKAGE_WHEEL}") + set(_wheel_final "${VA_PYTHON_PACKAGE_PATH}/dist/${VA_PYTHON_PACKAGE_WHEEL_FINAL}") + + if (NOT EXISTS "${_wheel}") message(FATAL_ERROR "Wheel not found") endif () - file(INSTALL ${_wheel} DESTINATION ${CMAKE_INSTALL_PREFIX}/${VA_PYTHON_OUTPUT_FOLDER}/) + file(COPY_FILE ${_wheel} ${_wheel_final}) + + file(INSTALL ${_wheel_final} DESTINATION ${CMAKE_INSTALL_PREFIX}/${VA_PYTHON_OUTPUT_FOLDER}/) ]] COMPONENT ${PROJECT_NAME} ) diff --git a/README.md b/README.md index 0ef06e83fef50b12b50ae785eb6f012e97c57320..d5cb4ac50f12f73e013e6f825db331a61b90413b 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,96 @@ # VAPython -VAPython is a C++ extension for the Python3 interpreter that provides a (networked) interface to VA. +VAPython is a pure Python binding for controlling a [Virtual Acoustics (VA)](https://www.virtualacoustics.org/) server. -## License +It utilizes the gRPC protocol to communicate with the VA server and provides a Pythonic interface to the VA API. +This is achieved through the use of [betterproto](https://github.com/danielgtaylor/python-betterproto). -Copyright 2015-2023 Institute of Technical Acoustics (ITA), RWTH Aachen University +## Requirements -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use files of this project except in compliance with the License. -You may obtain a copy of the License at +Python 3.9 or higher. -<http://www.apache.org/licenses/LICENSE-2.0> +## Install -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +The downloaded package contains a wheel file that can be installed using pip: -## Requirements +```bash +pip install VAPython-<version>-py3-none-any.whl +``` -Python 3.8 or higher. +where `<version>` is the version of the package,e.g. `v2024a`. -## Install +Once installed, the package can be imported and used like this: + +```python +from vapython import VA + +va = VA() # create a VA object +va.connect() # connect to the VA server +``` -The VA binary packages come with a wheel installer. -The wheel supports all versions above 3.8. -It can be installed using pip from the respective main folder with: +This way, the Python commands will be comparable to the commands of VAMatlab. + +## Examples + +This binding includes examples that demonstrate how to use the API. +These can be found in the `examples` directory of the package. + +When VAPython is installed, the examples can be run like this: ```bash -pip install VAPython-2022.0-cp38-abi3-win_amd64.whl +python -m vapython.examples.<example_name> ``` -Remember to adapt the release version (here `2022.0`) in the command above. -Afterwards, you can start a VAServer and try the `va_example_simple.py` script in the *example* folder. +Or via the included example runner: -## Quick build guide +```bash +python -m vapython.examples.__main__ +``` -VAPython can be built from the [VA](https://git.rwth-aachen.de/ita/VA) base project. -Further build instructions can be found [here](https://git.rwth-aachen.de/ita/ITACoreLibs/-/wikis/home#build-guide). -During configuration, the variable `ITA_VA_WITH_BINDING_PYTHON` must be set to enable the build for VAPython. -Afterwards, the CMake target for VAPython can be built or a wheel generated with the `wheel` target. +## Development guide -## Using +VAPython uses [hatch](https://hatch.pypa.io/dev/) for packaging and building. -Within Python, the module is called `VAPython`. It is generally recommended to import using the *va* alias: +Building in this case means generating the Python files from the proto files and rendering the template for the wrapper. +In case changes are made to the proto files, the build scripts or the template, the build process has to be triggered manually. +This can be done by running the following command in the root directory of the project: -```python -import VAPython as va +```bash +hatch build +``` + +Optionally, + +```bash +hatch build -t wheel +``` + +can be used to only build a wheel package (and save some time). + +When only changes are made to the Python files, the build process is not necessary. +In this case it is recommended to use the default environment of hatch which includes a editable install of the package. +This is also the environment in which the tests are run. + +### Running the examples + +When developing and using hatch, the examples runner can also be called via hatch: + +```bash +hatch run examples ``` -This way, the Python commands will be mostly comparable to the commands of VAMatlab. +## License + +Copyright 2015-2023 Institute of Technical Acoustics (ITA), RWTH Aachen University + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use files of this project except in compliance with the License. +You may obtain a copy of the License at + +<http://www.apache.org/licenses/LICENSE-2.0> + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/pyproject.toml b/pyproject.toml index d2f8e285256d133200c8e994f3fce92a499e664b..963624e9b170500b40ea1ab6ffb386cc4eebe171 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,7 @@ dependencies = [ "jinja2", ] [tool.hatch.envs.default.scripts] +examples = "py -m vapython.examples.__main__ {args:.}" test = "pytest {args:tests}" test-cov = "coverage run -m pytest {args:tests}" cov-report = [ diff --git a/src/vapython/examples/__main__.py b/src/vapython/examples/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..1e3f4b5d162f3d70ca8406bab315b9430b58c72b --- /dev/null +++ b/src/vapython/examples/__main__.py @@ -0,0 +1,40 @@ +import importlib +import sys +from pathlib import Path + + +def main(): + current_path = Path(__file__).parent + + example_files = list(current_path.glob("*example*.py")) + + if len(sys.argv) == 1: + for i, example_file in enumerate(example_files): + print(f"{i}: {example_file.stem}") + + print(f"{len(example_files)}: Exit") + + example_index = int(input("Enter the index of the example you want to run: ")) + else: + example_index = int(sys.argv[1]) + + if example_index == len(example_files): + return + + if example_index < 0 or example_index >= len(example_files): + print("Invalid index") + return + + example_file = example_files[example_index] + module_name = f"pigeon.examples.{example_file.stem}" + module = importlib.import_module(module_name) + + example_main = getattr(module, "main", None) + if example_main is not None: + example_main() + else: + print(f"Could not find 'main' function in module '{module_name}'") + + +if __name__ == "__main__": + main()