From 2a2c3385243ccdd559fe8ffc7eec0bb659096193 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Mon, 6 Oct 2025 15:14:23 -0500 Subject: [PATCH 01/23] Use analyze-project from ni/python-actions --- .github/workflows/check_nimg.yml | 18 +++---------- .github/workflows/check_nims.yml | 44 ++++---------------------------- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index f656d274a..6c45e3698 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -20,22 +20,10 @@ jobs: id: setup-python - name: Set up Poetry uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 - - name: Check for lock changes (ni-measurement-plugin-sdk-generator) - run: poetry check --lock - - name: Cache virtualenv (ni-measurement-plugin-sdk-generator) - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 - id: cache + - name: Analyze generator + uses: ni/python-actions/analyze-project@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 with: - path: packages/generator/.venv - key: ni-measurement-plugin-sdk-generator-${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('packages/generator/poetry.lock') }} - - name: Install ni-measurement-plugin-sdk-generator - run: poetry install -v - - name: Lint ni-measurement-plugin-sdk-generator - run: poetry run ni-python-styleguide lint - - name: Mypy static analysis (ni-measurement-plugin-sdk-generator, Linux) - run: poetry run mypy - - name: Mypy static analysis (ni-measurement-plugin-sdk-generator, Windows) - run: poetry run mypy --platform win32 + project-directory: packages/generator - name: Bandit security checks (ni-measurement-plugin-sdk-generator, example_renders) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_generator tests/test_assets/example_renders - name: Generate gRPC stubs diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index 2fa8f3a03..68462323d 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -22,48 +22,14 @@ jobs: id: setup-python - name: Set up Poetry uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 - - name: Check for lock changes (ni-measurement-plugin-sdk-service) - run: poetry check --lock - - # ni-measurement-plugin-sdk-service, all extras - - name: Restore cached virtualenv (ni-measurement-plugin-sdk-service, all extras) - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 - id: restore-nims-all-extras - with: - path: packages/service/.venv - key: ni-measurement-plugin-sdk-service-all-extras-${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('packages/service/poetry.lock') }} - - name: Install ni-measurement-plugin-sdk-service (all extras) - run: poetry install -v --all-extras - - name: Save cached virtualenv (ni-measurement-plugin-sdk-service, all extras) - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 - if: steps.restore-nims-all-extras.outputs.cache-hit != 'true' + # ni-measurement-plugin-sdk-service, all extras, docs + - name: Analyze generator + uses: ni/python-actions/analyze-project@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 with: - path: packages/service/.venv - key: ${{ steps.restore-nims-all-extras.outputs.cache-primary-key }} - - name: Lint ni-measurement-plugin-sdk-service - run: poetry run ni-python-styleguide lint - - name: Mypy static analysis (ni-measurement-plugin-sdk-service, Linux) - run: poetry run mypy - - name: Mypy static analysis (ni-measurement-plugin-sdk-service, Windows) - run: poetry run mypy --platform win32 + project-directory: packages/service + install-args: --all-extras --with docs - name: Bandit security checks (ni-measurement-plugin-sdk-service) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_service - - # ni-measurement-plugin-sdk-service, all extras, docs - - name: Restore cached virtualenv (ni-measurement-plugin-sdk-service, all extras, docs) - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 - id: restore-nims-all-extras-docs - with: - path: packages/service/.venv - key: ni-measurement-plugin-sdk-service-all-extras-docs-${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('packages/service/poetry.lock') }} - - name: Install ni-measurement-plugin-sdk-service (all extras, docs) - run: poetry install -v --all-extras --with docs - - name: Save cached virtualenv (ni-measurement-plugin-sdk-service, all extras, docs) - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 - if: steps.restore-nims-all-extras-docs.outputs.cache-hit != 'true' - with: - path: packages/service/.venv - key: ${{ steps.restore-nims-all-extras-docs.outputs.cache-primary-key }} - name: Build docs and check for errors/warnings run: | rm -rf docs From 2957f089071d85a89665858eff11cb77a80e6918 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 13:16:01 -0500 Subject: [PATCH 02/23] Add check docs. Add matrix checking for analyze-project --- .github/workflows/CI.yml | 4 ++++ .github/workflows/check_nimg.yml | 8 ++++++- .github/workflows/check_nims.yml | 18 +++++++-------- .github/workflows/check_nims_docs.yml | 32 +++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/check_nims_docs.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6514d043d..12ea4b1b7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,6 +12,10 @@ jobs: check_nims: name: Check NIMS uses: ./.github/workflows/check_nims.yml + check_nims_docs: + name: Check NIMS docs + uses: ./.github/workflows/check_nims_docs.yml + needs: [check_nims] check_nimg: name: Check NIMG uses: ./.github/workflows/check_nimg.yml diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index 6c45e3698..651189a0e 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -7,7 +7,11 @@ on: jobs: check_nimg: name: Check NIMG - runs-on: ubuntu-latest + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + python-version: [3.9, 3.13] + runs-on: ${{ matrix.os }} defaults: run: # Set the working-directory for all steps in this job. @@ -18,6 +22,8 @@ jobs: - name: Set up Python uses: ni/python-actions/setup-python@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 id: setup-python + with: + python-version: ${{ matrix.python-version }} - name: Set up Poetry uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 - name: Analyze generator diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index 68462323d..ada8e4454 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -7,7 +7,11 @@ on: jobs: check_nims: name: Check NIMS - runs-on: ubuntu-latest + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + python-version: [3.9, 3.13] + runs-on: ${{ matrix.os }} defaults: run: # Set the working-directory for all steps in this job. @@ -20,23 +24,17 @@ jobs: - name: Set up Python uses: ni/python-actions/setup-python@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 id: setup-python + with: + python-version: ${{ matrix.python-version }} - name: Set up Poetry uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 - # ni-measurement-plugin-sdk-service, all extras, docs - name: Analyze generator uses: ni/python-actions/analyze-project@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 with: project-directory: packages/service - install-args: --all-extras --with docs + install-args: --all-extras - name: Bandit security checks (ni-measurement-plugin-sdk-service) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_service - - name: Build docs and check for errors/warnings - run: | - rm -rf docs - mkdir -p docs - poetry run sphinx-build _docs_source docs -b html -W - - name: Revert docs - run: rm -rf docs - name: Generate gRPC stubs run: | find tests/utilities/stubs/ -name \*_pb2.py\* -o -name \*_pb2_grpc.py\* -delete diff --git a/.github/workflows/check_nims_docs.yml b/.github/workflows/check_nims_docs.yml new file mode 100644 index 000000000..41d6c1756 --- /dev/null +++ b/.github/workflows/check_nims_docs.yml @@ -0,0 +1,32 @@ +name: Check NIMS Docs + +on: + workflow_call: + workflow_dispatch: + +jobs: + check_nims: + name: Check NIMS Docs + runs-on: ubuntu-latest + defaults: + run: + # Set the working-directory for all steps in this job. + working-directory: ./packages/service + steps: + - name: Check out repo + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + submodules: true + - name: Set up Python + uses: ni/python-actions/setup-python@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 + id: setup-python + - name: Set up Poetry + uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 + # ni-measurement-plugin-sdk-service, all extras, docs + - name: Build docs and check for errors/warnings + run: | + rm -rf docs + mkdir -p docs + poetry run sphinx-build _docs_source docs -b html -W + - name: Revert docs + run: rm -rf docs \ No newline at end of file From 2bd22d9a6ccb38f4454c07783b5838abbc17eae6 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 13:34:27 -0500 Subject: [PATCH 03/23] Minor cleanup --- .github/workflows/CI.yml | 1 - .github/workflows/check_nimg.yml | 1 + .github/workflows/check_nims.yml | 1 + .../ni_measurement_plugin_sdk_service/_configuration.py | 5 +++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 12ea4b1b7..948039690 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,7 +15,6 @@ jobs: check_nims_docs: name: Check NIMS docs uses: ./.github/workflows/check_nims_docs.yml - needs: [check_nims] check_nimg: name: Check NIMG uses: ./.github/workflows/check_nimg.yml diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index 651189a0e..f785f0a46 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -11,6 +11,7 @@ jobs: matrix: os: [windows-latest, ubuntu-latest, macos-latest] python-version: [3.9, 3.13] + fail-fast: false runs-on: ${{ matrix.os }} defaults: run: diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index ada8e4454..d02395213 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -11,6 +11,7 @@ jobs: matrix: os: [windows-latest, ubuntu-latest, macos-latest] python-version: [3.9, 3.13] + fail-fast: false runs-on: ${{ matrix.os }} defaults: run: diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index d2122583b..d7f905156 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,8 +18,6 @@ _PREFIX = "MEASUREMENT_PLUGIN" -_config = AutoConfig(str(get_dotenv_search_path())) - if TYPE_CHECKING: # Work around decouple's lack of type hints. _T = TypeVar("_T") @@ -30,6 +28,9 @@ def _config( cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... +else: + _config = AutoConfig(str(get_dotenv_search_path())) + # ---------------------------------------------------------------------- # NI Modular Instrument Driver Options From 4e688f8b8387ce23d217ff1a8000fb71eda31111 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 13:56:36 -0500 Subject: [PATCH 04/23] Only check for out-of-date stubs with oldest Python version --- packages/service/poetry.lock | 30 ++++++++++++++++++++++-------- packages/service/pyproject.toml | 3 ++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/service/poetry.lock b/packages/service/poetry.lock index d22f8857a..59819e38c 100644 --- a/packages/service/poetry.lock +++ b/packages/service/poetry.lock @@ -33,6 +33,7 @@ description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" groups = ["docs"] +markers = "python_version <= \"3.11\"" files = [ {file = "astroid-3.3.11-py3-none-any.whl", hash = "sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec"}, {file = "astroid-3.3.11.tar.gz", hash = "sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce"}, @@ -41,6 +42,19 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} +[[package]] +name = "astroid" +version = "4.0.0" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.10.0" +groups = ["docs"] +markers = "python_version >= \"3.12\"" +files = [ + {file = "astroid-4.0.0-py3-none-any.whl", hash = "sha256:235980d60cdf94f63d1084d6e7fb4c1718a7f461149fc5800834e4625632f5ac"}, + {file = "astroid-4.0.0.tar.gz", hash = "sha256:b1bf640a2dbd198e26516fce7757f6484a28fb6e77d8d19eb965bf84d4c0997b"}, +] + [[package]] name = "babel" version = "2.17.0" @@ -144,14 +158,14 @@ files = [ [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.10.5" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main", "docs"] files = [ - {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, - {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, + {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, + {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, ] markers = {main = "extra == \"drivers\" or extra == \"nidaqmx\""} @@ -2539,20 +2553,20 @@ test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "pytest-xdis [[package]] name = "sphinx-autoapi" -version = "3.6.0" +version = "3.6.1" description = "Sphinx API documentation generator" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ - {file = "sphinx_autoapi-3.6.0-py3-none-any.whl", hash = "sha256:f3b66714493cab140b0e896d33ce7137654a16ac1edb6563edcbd47bf975f711"}, - {file = "sphinx_autoapi-3.6.0.tar.gz", hash = "sha256:c685f274e41d0842ae7e199460c322c4bd7fec816ccc2da8d806094b4f64af06"}, + {file = "sphinx_autoapi-3.6.1-py3-none-any.whl", hash = "sha256:6b7af0d5650f6eac1f4b85c1eb9f9a4911160ec7138bdc4451c77a5e94d5832c"}, + {file = "sphinx_autoapi-3.6.1.tar.gz", hash = "sha256:1ff2992b7d5e39ccf92413098a376e0f91e7b4ca532c4f3e71298dbc8a4a9900"}, ] [package.dependencies] astroid = [ - {version = ">=2.7", markers = "python_version < \"3.12\""}, - {version = ">=3", markers = "python_version >= \"3.12\""}, + {version = ">=3.0,<4.0", markers = "python_version < \"3.12\""}, + {version = ">=4.0,<5.0", markers = "python_version >= \"3.12\""}, ] Jinja2 = "*" PyYAML = "*" diff --git a/packages/service/pyproject.toml b/packages/service/pyproject.toml index 4226d4aaf..1b124ebe4 100644 --- a/packages/service/pyproject.toml +++ b/packages/service/pyproject.toml @@ -99,8 +99,9 @@ numpy = [ { version = ">=2.1", python = "^3.13"}, ] bandit = { version = ">=1.7", extras = ["toml"] } -# Install traceloggingdynamic on Linux for type checking. +# Install traceloggingdynamic on Linux and MacOS for type checking. traceloggingdynamic = { version = ">=1.0", platform = "linux" } +traceloggingdynamic = { version = ">=1.0", platform = "darwin" } [tool.poetry.group.docs] optional = true From e71dd1f24603c24e1b723a41d6b21cd523115c00 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 14:04:13 -0500 Subject: [PATCH 05/23] Fix traceloggingdynamic configuration --- .github/workflows/check_nimg.yml | 3 +++ .github/workflows/check_nims.yml | 3 +++ .github/workflows/check_nims_docs.yml | 3 ++- packages/service/poetry.lock | 4 ++-- packages/service/pyproject.toml | 6 ++++-- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index f785f0a46..cf51a72da 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -34,12 +34,15 @@ jobs: - name: Bandit security checks (ni-measurement-plugin-sdk-generator, example_renders) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_generator tests/test_assets/example_renders - name: Generate gRPC stubs + if: matrix.python-version == '3.9' run: | find tests/utilities/measurements/non_streaming_data_measurement/_stubs -name \*_pb2.py\* -o -name \*_pb2_grpc.py\* -delete poetry run python scripts/generate_grpc_stubs.py - name: Check for out-of-date gRPC stubs + if: matrix.python-version == '3.9' run: git diff --exit-code - name: Revert gRPC stubs + if: matrix.python-version == '3.9' run: | git clean -dfx tests/utilities/measurements/non_streaming_data_measurement/_stubs git restore tests/utilities/measurements/non_streaming_data_measurement/_stubs diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index d02395213..0d511f8c5 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -37,12 +37,15 @@ jobs: - name: Bandit security checks (ni-measurement-plugin-sdk-service) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_service - name: Generate gRPC stubs + if: matrix.python-version == '3.9' run: | find tests/utilities/stubs/ -name \*_pb2.py\* -o -name \*_pb2_grpc.py\* -delete poetry run python scripts/generate_grpc_stubs.py - name: Check for out-of-date gRPC stubs + if: matrix.python-version == '3.9' run: git diff --exit-code - name: Revert gRPC stubs + if: matrix.python-version == '3.9' run: | git clean -dfx tests/utilities/stubs/ git restore tests/utilities/stubs/ diff --git a/.github/workflows/check_nims_docs.yml b/.github/workflows/check_nims_docs.yml index 41d6c1756..0c9f5ec7f 100644 --- a/.github/workflows/check_nims_docs.yml +++ b/.github/workflows/check_nims_docs.yml @@ -22,7 +22,8 @@ jobs: id: setup-python - name: Set up Poetry uses: ni/python-actions/setup-poetry@9768589f3e50672173dad75a6fc181e4a85d33fa # v0.7.0 - # ni-measurement-plugin-sdk-service, all extras, docs + - name: Install ni-measurement-plugin-sdk-service (all extras, docs) + run: poetry install -v --all-extras --with docs - name: Build docs and check for errors/warnings run: | rm -rf docs diff --git a/packages/service/poetry.lock b/packages/service/poetry.lock index 59819e38c..eb4ad147e 100644 --- a/packages/service/poetry.lock +++ b/packages/service/poetry.lock @@ -2867,7 +2867,7 @@ description = "Generates Event Tracing for Windows events using TraceLogging" optional = false python-versions = ">=3.6" groups = ["main", "dev"] -markers = "sys_platform == \"win32\" or sys_platform == \"linux\"" +markers = "sys_platform == \"win32\" or sys_platform == \"linux\" or sys_platform == \"darwin\"" files = [ {file = "traceloggingdynamic-1.0.1-py3-none-any.whl", hash = "sha256:0e19da491a8960725b3622366487ae35f49d8f595bb2e4e5ce1795eb5928db7c"}, {file = "traceloggingdynamic-1.0.1.tar.gz", hash = "sha256:d9dd4b291dd04c15e34181eed06f73fdf4ffa7b1f895b78217163def48ab1a52"}, @@ -3053,4 +3053,4 @@ niswitch = ["niswitch"] [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "156f20176ad6808243ffd36d0b50c485e232998df51335016558a79048ff18f2" +content-hash = "4d18f4c7e37b52674e9a64c0c35afc0025f998fe0fa733d3e912f2b514a58c19" diff --git a/packages/service/pyproject.toml b/packages/service/pyproject.toml index 1b124ebe4..ebce63035 100644 --- a/packages/service/pyproject.toml +++ b/packages/service/pyproject.toml @@ -100,8 +100,10 @@ numpy = [ ] bandit = { version = ">=1.7", extras = ["toml"] } # Install traceloggingdynamic on Linux and MacOS for type checking. -traceloggingdynamic = { version = ">=1.0", platform = "linux" } -traceloggingdynamic = { version = ">=1.0", platform = "darwin" } +traceloggingdynamic = [ + { version = ">=1.0", platform = "linux" }, + { version = ">=1.0", platform = "darwin" }, +] [tool.poetry.group.docs] optional = true From 015ab46671fd56fa8db20062491ea88194bf63ec Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 14:17:23 -0500 Subject: [PATCH 06/23] Fix _config typing --- .../ni_measurement_plugin_sdk_service/_configuration.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index d7f905156..d2122583b 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,6 +18,8 @@ _PREFIX = "MEASUREMENT_PLUGIN" +_config = AutoConfig(str(get_dotenv_search_path())) + if TYPE_CHECKING: # Work around decouple's lack of type hints. _T = TypeVar("_T") @@ -28,9 +30,6 @@ def _config( cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... -else: - _config = AutoConfig(str(get_dotenv_search_path())) - # ---------------------------------------------------------------------- # NI Modular Instrument Driver Options From 3ad6ad3800de0c41d4a8953b820dd18ea0e22bb6 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 14:28:44 -0500 Subject: [PATCH 07/23] Fix _config typing --- .../ni_measurement_plugin_sdk_service/_configuration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index d2122583b..f808275c3 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,8 +18,6 @@ _PREFIX = "MEASUREMENT_PLUGIN" -_config = AutoConfig(str(get_dotenv_search_path())) - if TYPE_CHECKING: # Work around decouple's lack of type hints. _T = TypeVar("_T") @@ -29,6 +27,8 @@ def _config( default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... +else: + _config = AutoConfig(str(get_dotenv_search_path())) # ---------------------------------------------------------------------- From dce58f1f0521857675285a00733eca380a73209f Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 14:47:20 -0500 Subject: [PATCH 08/23] Fix lint error --- .../service/ni_measurement_plugin_sdk_service/_configuration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index f808275c3..d7f905156 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -27,6 +27,7 @@ def _config( default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... + else: _config = AutoConfig(str(get_dotenv_search_path())) From 23516cf43a29c4167fadb67fe38afae3802eb875 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 15:01:02 -0500 Subject: [PATCH 09/23] Fix lint error --- .../_configuration.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index d7f905156..0507970f4 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,18 +18,21 @@ _PREFIX = "MEASUREMENT_PLUGIN" +# Create the config instance - always available for imports +_config = AutoConfig(str(get_dotenv_search_path())) + if TYPE_CHECKING: - # Work around decouple's lack of type hints. + # Work around decouple's lack of type hints by redefining the type _T = TypeVar("_T") - def _config( + def __config_stub( option: str, default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... -else: - _config = AutoConfig(str(get_dotenv_search_path())) + # Tell type checker this is the real signature + _config = __config_stub # ---------------------------------------------------------------------- From 93cc67c7fbe2cdfd0df1ae4561fff4fc1faa11fe Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 15:45:43 -0500 Subject: [PATCH 10/23] PR feedback from Brad --- .github/workflows/check_nimg.yml | 8 +++-- .github/workflows/check_nims.yml | 8 +++-- .../_configuration.py | 9 +++-- .../_tracelogging.py | 35 +++++++++---------- packages/service/pyproject.toml | 4 --- 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index cf51a72da..35ba773d3 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -7,6 +7,8 @@ on: jobs: check_nimg: name: Check NIMG + env: + oldest-python-version: '3.9' strategy: matrix: os: [windows-latest, ubuntu-latest, macos-latest] @@ -34,15 +36,15 @@ jobs: - name: Bandit security checks (ni-measurement-plugin-sdk-generator, example_renders) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_generator tests/test_assets/example_renders - name: Generate gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: | find tests/utilities/measurements/non_streaming_data_measurement/_stubs -name \*_pb2.py\* -o -name \*_pb2_grpc.py\* -delete poetry run python scripts/generate_grpc_stubs.py - name: Check for out-of-date gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: git diff --exit-code - name: Revert gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: | git clean -dfx tests/utilities/measurements/non_streaming_data_measurement/_stubs git restore tests/utilities/measurements/non_streaming_data_measurement/_stubs diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index 0d511f8c5..bc3acc3fd 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -7,6 +7,8 @@ on: jobs: check_nims: name: Check NIMS + env: + oldest-python-version: '3.9' strategy: matrix: os: [windows-latest, ubuntu-latest, macos-latest] @@ -37,15 +39,15 @@ jobs: - name: Bandit security checks (ni-measurement-plugin-sdk-service) run: poetry run bandit -c pyproject.toml -r ni_measurement_plugin_sdk_service - name: Generate gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: | find tests/utilities/stubs/ -name \*_pb2.py\* -o -name \*_pb2_grpc.py\* -delete poetry run python scripts/generate_grpc_stubs.py - name: Check for out-of-date gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: git diff --exit-code - name: Revert gRPC stubs - if: matrix.python-version == '3.9' + if: matrix.python-version == env.oldest-python-version run: | git clean -dfx tests/utilities/stubs/ git restore tests/utilities/stubs/ diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index 0507970f4..b3f6bb66c 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,19 +18,18 @@ _PREFIX = "MEASUREMENT_PLUGIN" -# Create the config instance - always available for imports -_config = AutoConfig(str(get_dotenv_search_path())) - if TYPE_CHECKING: - # Work around decouple's lack of type hints by redefining the type + # Work around decouple's lack of type hints. _T = TypeVar("_T") - def __config_stub( + def _config( option: str, default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... +else: + _config = AutoConfig(str(get_dotenv_search_path())) # Tell type checker this is the real signature _config = __config_stub diff --git a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py b/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py index 8d0d33523..343167205 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py @@ -6,20 +6,19 @@ from typing import TYPE_CHECKING if sys.platform == "win32": - try: - import traceloggingdynamic + import traceloggingdynamic - _event_provider: traceloggingdynamic.Provider | None = traceloggingdynamic.Provider( - b"NI-Measurement-Plug-In-Python" - ) - except ImportError: - _event_provider = None -else: - if TYPE_CHECKING: - import traceloggingdynamic + _event_provider = traceloggingdynamic.Provider(b"NI-Measurement-Plug-In-Python") + + def _create_event_builder() -> traceloggingdynamic.EventBuilder: + return traceloggingdynamic.EventBuilder() +else: _event_provider = None + def _create_event_builder() -> Any: + raise RuntimeError(f"ETW logging is not supported on {sys.platform}") + _LEVEL_LOG_ALWAYS = 0 _LEVEL_CRITICAL = 1 _LEVEL_ERROR = 3 @@ -87,7 +86,7 @@ def is_enabled() -> bool: def log_grpc_client_call_start(method_name: str) -> uuid.UUID | None: """Log when starting a gRPC client call.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcClientCall", level=_LEVEL_INFO, @@ -107,7 +106,7 @@ def log_grpc_client_call_start(method_name: str) -> uuid.UUID | None: def log_grpc_client_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: """Log when a gRPC client call has completed.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcClientCall", level=_LEVEL_INFO, @@ -122,7 +121,7 @@ def log_grpc_client_call_stop(method_name: str, activity_id: uuid.UUID | None = def log_grpc_client_call_streaming_request(method_name: str) -> None: """Log when a gRPC client call is sending a client-streaming request.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcClientCallStreamingRequest", level=_LEVEL_INFO, @@ -136,7 +135,7 @@ def log_grpc_client_call_streaming_request(method_name: str) -> None: def log_grpc_client_call_streaming_response(method_name: str) -> None: """Log when a gRPC client call has received a server-streaming response.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcClientCallStreamingResponse", level=_LEVEL_INFO, @@ -150,7 +149,7 @@ def log_grpc_client_call_streaming_response(method_name: str) -> None: def log_grpc_server_call_start(method_name: str) -> uuid.UUID | None: """Log when starting a gRPC server call.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcServerCall", level=_LEVEL_INFO, @@ -170,7 +169,7 @@ def log_grpc_server_call_start(method_name: str) -> uuid.UUID | None: def log_grpc_server_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: """Log when a gRPC server call has completed.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcServerCall", level=_LEVEL_INFO, @@ -185,7 +184,7 @@ def log_grpc_server_call_stop(method_name: str, activity_id: uuid.UUID | None = def log_grpc_server_call_streaming_request(method_name: str) -> None: """Log when a gRPC server call is sending a server-streaming request.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcServerCallStreamingRequest", level=_LEVEL_INFO, @@ -199,7 +198,7 @@ def log_grpc_server_call_streaming_request(method_name: str) -> None: def log_grpc_server_call_streaming_response(method_name: str) -> None: """Log when a gRPC server call has received a server-streaming response.""" if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = traceloggingdynamic.EventBuilder() + eb = _create_event_builder() eb.reset( b"GrpcServerCallStreamingResponse", level=_LEVEL_INFO, diff --git a/packages/service/pyproject.toml b/packages/service/pyproject.toml index ebce63035..c95ca23aa 100644 --- a/packages/service/pyproject.toml +++ b/packages/service/pyproject.toml @@ -100,10 +100,6 @@ numpy = [ ] bandit = { version = ">=1.7", extras = ["toml"] } # Install traceloggingdynamic on Linux and MacOS for type checking. -traceloggingdynamic = [ - { version = ">=1.0", platform = "linux" }, - { version = ">=1.0", platform = "darwin" }, -] [tool.poetry.group.docs] optional = true From 1b9bd07755bed841c56d55541927fd2198c7234b Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 15:50:50 -0500 Subject: [PATCH 11/23] Remove unused comment. Re-lock service package --- packages/service/poetry.lock | 10 +++++----- packages/service/pyproject.toml | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/service/poetry.lock b/packages/service/poetry.lock index eb4ad147e..755735d4c 100644 --- a/packages/service/poetry.lock +++ b/packages/service/poetry.lock @@ -298,7 +298,7 @@ files = [ {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, ] -markers = {main = "(extra == \"drivers\" or extra == \"nidaqmx\") and python_version >= \"3.10\"", dev = "python_version >= \"3.10\"", docs = "python_version >= \"3.10\""} +markers = {main = "python_version >= \"3.10\" and (extra == \"drivers\" or extra == \"nidaqmx\")", dev = "python_version >= \"3.10\"", docs = "python_version >= \"3.10\""} [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -2866,8 +2866,8 @@ version = "1.0.1" description = "Generates Event Tracing for Windows events using TraceLogging" optional = false python-versions = ">=3.6" -groups = ["main", "dev"] -markers = "sys_platform == \"win32\" or sys_platform == \"linux\" or sys_platform == \"darwin\"" +groups = ["main"] +markers = "sys_platform == \"win32\"" files = [ {file = "traceloggingdynamic-1.0.1-py3-none-any.whl", hash = "sha256:0e19da491a8960725b3622366487ae35f49d8f595bb2e4e5ce1795eb5928db7c"}, {file = "traceloggingdynamic-1.0.1.tar.gz", hash = "sha256:d9dd4b291dd04c15e34181eed06f73fdf4ffa7b1f895b78217163def48ab1a52"}, @@ -2953,7 +2953,7 @@ description = "Provider of IANA time zone data" optional = true python-versions = ">=2" groups = ["main"] -markers = "(extra == \"drivers\" or extra == \"nidaqmx\") and platform_system == \"Windows\"" +markers = "platform_system == \"Windows\" and (extra == \"drivers\" or extra == \"nidaqmx\")" files = [ {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, @@ -3053,4 +3053,4 @@ niswitch = ["niswitch"] [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "4d18f4c7e37b52674e9a64c0c35afc0025f998fe0fa733d3e912f2b514a58c19" +content-hash = "a3ac389b98b8893c2a2831abd8742dafb23bf173689a4219a81a3607cc52fcd2" diff --git a/packages/service/pyproject.toml b/packages/service/pyproject.toml index c95ca23aa..3c393e9bf 100644 --- a/packages/service/pyproject.toml +++ b/packages/service/pyproject.toml @@ -99,7 +99,6 @@ numpy = [ { version = ">=2.1", python = "^3.13"}, ] bandit = { version = ">=1.7", extras = ["toml"] } -# Install traceloggingdynamic on Linux and MacOS for type checking. [tool.poetry.group.docs] optional = true From 231135a3476310aec208191f46632a3a336b1557 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 15:59:14 -0500 Subject: [PATCH 12/23] Fix check NIMS --- .../ni_measurement_plugin_sdk_service/_configuration.py | 2 -- .../service/ni_measurement_plugin_sdk_service/_tracelogging.py | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index b3f6bb66c..d7f905156 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -30,8 +30,6 @@ def _config( else: _config = AutoConfig(str(get_dotenv_search_path())) - # Tell type checker this is the real signature - _config = __config_stub # ---------------------------------------------------------------------- diff --git a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py b/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py index 343167205..cc0ce2369 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py @@ -3,7 +3,7 @@ import ctypes import sys import uuid -from typing import TYPE_CHECKING +from typing import Any if sys.platform == "win32": import traceloggingdynamic @@ -19,6 +19,7 @@ def _create_event_builder() -> traceloggingdynamic.EventBuilder: def _create_event_builder() -> Any: raise RuntimeError(f"ETW logging is not supported on {sys.platform}") + _LEVEL_LOG_ALWAYS = 0 _LEVEL_CRITICAL = 1 _LEVEL_ERROR = 3 From 05b0292220b50dd7ad1da80a80c8889ffb961ab4 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 16:08:50 -0500 Subject: [PATCH 13/23] Fix _config import error --- .../ni_measurement_plugin_sdk_service/_configuration.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index d7f905156..04264661d 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -18,19 +18,20 @@ _PREFIX = "MEASUREMENT_PLUGIN" -if TYPE_CHECKING: - # Work around decouple's lack of type hints. - _T = TypeVar("_T") +# Work around decouple's lack of type hints. +_T = TypeVar("_T") +if TYPE_CHECKING: def _config( option: str, default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, ) -> _T: ... - else: _config = AutoConfig(str(get_dotenv_search_path())) +__all__ = ["_PREFIX", "_config"] + # ---------------------------------------------------------------------- # NI Modular Instrument Driver Options From 4eb2583043fb90296fd507696e01cecd4e08c9a3 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Tue, 7 Oct 2025 16:17:17 -0500 Subject: [PATCH 14/23] Fix nps errors --- .../ni_measurement_plugin_sdk_service/_configuration.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index 04264661d..0d66de7fe 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -22,11 +22,15 @@ _T = TypeVar("_T") if TYPE_CHECKING: + def _config( option: str, default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, - ) -> _T: ... + ) -> _T: + """Get configuration value from environment or config file.""" + ... + else: _config = AutoConfig(str(get_dotenv_search_path())) From 305302e112f17ed05633a17466a9d63dfde1e2c8 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 09:58:34 -0500 Subject: [PATCH 15/23] Add all other exports to __all__ --- .../_configuration.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index 0d66de7fe..5c66acd29 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -34,7 +34,21 @@ def _config( else: _config = AutoConfig(str(get_dotenv_search_path())) -__all__ = ["_PREFIX", "_config"] +__all__ = [ + "_PREFIX", + "_config", + "MIDriverOptions", + "NISwitchOptions", + "NIDCPOWER_OPTIONS", + "NIDIGITAL_OPTIONS", + "NIDMM_OPTIONS", + "NIFGEN_OPTIONS", + "NISCOPE_OPTIONS", + "NISWITCH_OPTIONS", + "NISWITCH_MULTIPLEXER_OPTIONS", + "USE_GRPC_DEVICE_SERVER", + "GRPC_DEVICE_SERVER_ADDRESS", +] # ---------------------------------------------------------------------- From 25a91f685f15138be7f8e631e1518fe53fabefab Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 10:02:08 -0500 Subject: [PATCH 16/23] Check docs at publish time. --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cbacf0380..1771c36fe 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -43,6 +43,9 @@ jobs: check_nims: name: Check service uses: ./.github/workflows/check_nims.yml + check_nims_docs: + name: Check NIMS docs + uses: ./.github/workflows/check_nims_docs.yml build_package: name: Build ${{ matrix.package }} runs-on: ubuntu-latest From fae207c1616ba851086731163e959b823ea1fe7e Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 15:28:04 -0500 Subject: [PATCH 17/23] Remove __all__ from _configuration.py --- .../_configuration.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index 5c66acd29..26f260420 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -34,22 +34,6 @@ def _config( else: _config = AutoConfig(str(get_dotenv_search_path())) -__all__ = [ - "_PREFIX", - "_config", - "MIDriverOptions", - "NISwitchOptions", - "NIDCPOWER_OPTIONS", - "NIDIGITAL_OPTIONS", - "NIDMM_OPTIONS", - "NIFGEN_OPTIONS", - "NISCOPE_OPTIONS", - "NISWITCH_OPTIONS", - "NISWITCH_MULTIPLEXER_OPTIONS", - "USE_GRPC_DEVICE_SERVER", - "GRPC_DEVICE_SERVER_ADDRESS", -] - # ---------------------------------------------------------------------- # NI Modular Instrument Driver Options From e18c572bd0bddef4d5cfe16cff60acafe63565bf Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 15:34:04 -0500 Subject: [PATCH 18/23] Remove fail-fast: false --- .github/workflows/check_nimg.yml | 1 - .github/workflows/check_nims.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/check_nimg.yml b/.github/workflows/check_nimg.yml index 35ba773d3..78a99192b 100644 --- a/.github/workflows/check_nimg.yml +++ b/.github/workflows/check_nimg.yml @@ -13,7 +13,6 @@ jobs: matrix: os: [windows-latest, ubuntu-latest, macos-latest] python-version: [3.9, 3.13] - fail-fast: false runs-on: ${{ matrix.os }} defaults: run: diff --git a/.github/workflows/check_nims.yml b/.github/workflows/check_nims.yml index bc3acc3fd..c7a4c9833 100644 --- a/.github/workflows/check_nims.yml +++ b/.github/workflows/check_nims.yml @@ -13,7 +13,6 @@ jobs: matrix: os: [windows-latest, ubuntu-latest, macos-latest] python-version: [3.9, 3.13] - fail-fast: false runs-on: ${{ matrix.os }} defaults: run: From 5b961d3c7e2dd7867d2f4cf48d28bb81c76d3b2e Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 15:35:53 -0500 Subject: [PATCH 19/23] Remove unneeded docstring --- .../ni_measurement_plugin_sdk_service/_configuration.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py index 26f260420..4cf3e3cc1 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/_configuration.py +++ b/packages/service/ni_measurement_plugin_sdk_service/_configuration.py @@ -27,9 +27,7 @@ def _config( option: str, default: _T | Undefined = undefined, cast: Callable[[str], _T] | Undefined = undefined, - ) -> _T: - """Get configuration value from environment or config file.""" - ... + ) -> _T: ... else: _config = AutoConfig(str(get_dotenv_search_path())) From 8a3b21ed5eb4ddbf4aa17734c56ac8659c66c6c3 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 15:36:15 -0500 Subject: [PATCH 20/23] Remove unneeded docstring --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1771c36fe..84038c5f9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -49,7 +49,7 @@ jobs: build_package: name: Build ${{ matrix.package }} runs-on: ubuntu-latest - needs: [check_nimg, check_nims] + needs: [check_nimg, check_nims, check_nims_docs] strategy: matrix: package: [generator, sdk, service] From 2281605bf32360c8553e1d805154ea374559c03b Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Wed, 8 Oct 2025 15:39:34 -0500 Subject: [PATCH 21/23] Remove traceloggingdynamic and _tracelogging.py --- .../_tracelogging.py | 210 ------------------ packages/service/poetry.lock | 2 +- packages/service/pyproject.toml | 1 - 3 files changed, 1 insertion(+), 212 deletions(-) delete mode 100644 packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py diff --git a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py b/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py deleted file mode 100644 index cc0ce2369..000000000 --- a/packages/service/ni_measurement_plugin_sdk_service/_tracelogging.py +++ /dev/null @@ -1,210 +0,0 @@ -from __future__ import annotations - -import ctypes -import sys -import uuid -from typing import Any - -if sys.platform == "win32": - import traceloggingdynamic - - _event_provider = traceloggingdynamic.Provider(b"NI-Measurement-Plug-In-Python") - - def _create_event_builder() -> traceloggingdynamic.EventBuilder: - return traceloggingdynamic.EventBuilder() - -else: - _event_provider = None - - def _create_event_builder() -> Any: - raise RuntimeError(f"ETW logging is not supported on {sys.platform}") - - -_LEVEL_LOG_ALWAYS = 0 -_LEVEL_CRITICAL = 1 -_LEVEL_ERROR = 3 -_LEVEL_WARNING = 3 -_LEVEL_INFO = 4 -_LEVEL_VERBOSE = 5 - -_OPCODE_INFO = 0 -_OPCODE_START = 1 -_OPCODE_STOP = 2 - -_KEYWORD_NONE = 0 -_KEYWORD_GRPC = 1 << 0 - -_TASK_GRPC_CLIENT_CALL = 1 -_TASK_GRPC_SERVER_CALL = 2 - - -if sys.platform == "win32": - # 0x00000800 = LOAD_LIBRARY_SEARCH_SYSTEM32 (Win8 or later) - _eventing_dll = ctypes.WinDLL("api-ms-win-eventing-provider-l1-1-0.dll", mode=0x00000800) - - _EventActivityIdControl = _eventing_dll.EventActivityIdControl - _EventActivityIdControl.restype = ctypes.c_uint32 - _EventActivityIdControl.argtypes = (ctypes.c_uint32, ctypes.c_void_p) - - _EVENT_ACTIVITY_CTRL_GET_ID = 1 - _EVENT_ACTIVITY_CTRL_SET_ID = 2 - _EVENT_ACTIVITY_CTRL_CREATE_ID = 3 - _EVENT_ACTIVITY_CTRL_GET_SET_ID = 4 - _EVENT_ACTIVITY_CTRL_CREATE_SET_ID = 5 - - def _create_activity_id() -> uuid.UUID: - activity_bytes = (ctypes.c_byte * 16)() - status = _EventActivityIdControl( - _EVENT_ACTIVITY_CTRL_CREATE_ID, ctypes.pointer(activity_bytes) - ) - if status != 0: - raise OSError("EventActivityIdControl error", status) - return uuid.UUID(bytes_le=bytes(activity_bytes)) - - def _get_current_thread_activity_id() -> uuid.UUID: - activity_bytes = (ctypes.c_byte * 16)() - status = _EventActivityIdControl( - _EVENT_ACTIVITY_CTRL_GET_ID, ctypes.pointer(activity_bytes) - ) - if status != 0: - raise OSError("EventActivityIdControl error", status) - return uuid.UUID(bytes_le=bytes(activity_bytes)) - -else: - - def _create_activity_id() -> uuid.UUID: - return uuid.uuid4() - - def _get_current_thread_activity_id() -> uuid.UUID: - return uuid.UUID() - - -def is_enabled() -> bool: - """Queries whether the event provider is enabled.""" - return _event_provider is not None and _event_provider.is_enabled() - - -def log_grpc_client_call_start(method_name: str) -> uuid.UUID | None: - """Log when starting a gRPC client call.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcClientCall", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_START, - task=_TASK_GRPC_CLIENT_CALL, - ) - eb.add_str8(b"FormattedMessage", "gRPC client call starting: " + method_name) - activity_id = _create_activity_id() - related_activity_id = _get_current_thread_activity_id() - _event_provider.write(eb, activity_id, related_activity_id) - return activity_id - else: - return None - - -def log_grpc_client_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: - """Log when a gRPC client call has completed.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcClientCall", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_STOP, - task=_TASK_GRPC_CLIENT_CALL, - ) - eb.add_str8(b"FormattedMessage", "gRPC client call complete: " + method_name) - _event_provider.write(eb, activity_id) - - -def log_grpc_client_call_streaming_request(method_name: str) -> None: - """Log when a gRPC client call is sending a client-streaming request.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcClientCallStreamingRequest", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_INFO, - ) - eb.add_str8(b"FormattedMessage", "gRPC client call streaming request: " + method_name) - _event_provider.write(eb) - - -def log_grpc_client_call_streaming_response(method_name: str) -> None: - """Log when a gRPC client call has received a server-streaming response.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcClientCallStreamingResponse", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_INFO, - ) - eb.add_str8(b"FormattedMessage", "gRPC client call streaming response: " + method_name) - _event_provider.write(eb) - - -def log_grpc_server_call_start(method_name: str) -> uuid.UUID | None: - """Log when starting a gRPC server call.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcServerCall", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_START, - task=_TASK_GRPC_SERVER_CALL, - ) - eb.add_str8(b"FormattedMessage", "gRPC server call starting: " + method_name) - activity_id = _create_activity_id() - related_activity_id = _get_current_thread_activity_id() - _event_provider.write(eb, activity_id, related_activity_id) - return activity_id - else: - return None - - -def log_grpc_server_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: - """Log when a gRPC server call has completed.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcServerCall", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_STOP, - task=_TASK_GRPC_SERVER_CALL, - ) - eb.add_str8(b"FormattedMessage", "gRPC server call complete: " + method_name) - _event_provider.write(eb, activity_id) - - -def log_grpc_server_call_streaming_request(method_name: str) -> None: - """Log when a gRPC server call is sending a server-streaming request.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcServerCallStreamingRequest", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_INFO, - ) - eb.add_str8(b"FormattedMessage", "gRPC server call streaming request: " + method_name) - _event_provider.write(eb) - - -def log_grpc_server_call_streaming_response(method_name: str) -> None: - """Log when a gRPC server call has received a server-streaming response.""" - if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): - eb = _create_event_builder() - eb.reset( - b"GrpcServerCallStreamingResponse", - level=_LEVEL_INFO, - keyword=_KEYWORD_GRPC, - opcode=_OPCODE_INFO, - ) - eb.add_str8(b"FormattedMessage", "gRPC server call streaming response: " + method_name) - _event_provider.write(eb) diff --git a/packages/service/poetry.lock b/packages/service/poetry.lock index 755735d4c..6d0f468ce 100644 --- a/packages/service/poetry.lock +++ b/packages/service/poetry.lock @@ -3053,4 +3053,4 @@ niswitch = ["niswitch"] [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "a3ac389b98b8893c2a2831abd8742dafb23bf173689a4219a81a3607cc52fcd2" +content-hash = "2974d8471748ed0cdc4965016f3352bc9d239abbc3544911b37c1e5d4d59df69" diff --git a/packages/service/pyproject.toml b/packages/service/pyproject.toml index 3c393e9bf..d723cbf92 100644 --- a/packages/service/pyproject.toml +++ b/packages/service/pyproject.toml @@ -34,7 +34,6 @@ grpcio = "^1.49.1" protobuf = ">=4.21" pywin32 = { version = ">=303", platform = "win32" } deprecation = ">=2.1" -traceloggingdynamic = { version = ">=1.0", platform = "win32" } python-decouple = ">=3.8" nidaqmx = { version = ">=0.8.0", extras = ["grpc"], optional = true } nidcpower = { version = ">=1.4.4", extras = ["grpc"], optional = true } From 875a557e6764907a37c03eb2e812717211ee7cf0 Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Thu, 9 Oct 2025 10:32:01 -0500 Subject: [PATCH 22/23] Add 'checks_succeeded' job to summarize matrix from check NIMS and check NIMG --- .github/workflows/CI.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 948039690..853af1a7a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,6 +18,12 @@ jobs: check_nimg: name: Check NIMG uses: ./.github/workflows/check_nimg.yml + checks_succeeded: + name: Checks succeeded + needs: [check_nims, check_nims_docs, check_nimg] + runs-on: ubuntu-latest + steps: + - run: exit 0 check_examples: name: Check examples uses: ./.github/workflows/check_examples.yml From 0559607b0147d57378ea8efcc0f9064467c6981c Mon Sep 17 00:00:00 2001 From: Joel Dixon Date: Thu, 9 Oct 2025 10:33:30 -0500 Subject: [PATCH 23/23] Add 'unit_tests_succeeded' job to summarize matrix unit test results --- .github/workflows/CI.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 853af1a7a..c157d9f08 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -31,6 +31,12 @@ jobs: name: Run unit tests uses: ./.github/workflows/run_unit_tests.yml needs: [check_nims] + unit_tests_succeeded: + name: Unit tests succeeded + needs: [run_unit_tests] + runs-on: ubuntu-latest + steps: + - run: exit 0 run_system_tests: name: Run system tests uses: ./.github/workflows/run_system_tests.yml