Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

service: Add driver-specific create_session(s) APIs for MI drivers #429

Merged
merged 22 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cbebcc1
pyproject.toml: Add extras for NI driver APIs
bkeryan Oct 2, 2023
4dfe291
Update poetry.lock
bkeryan Oct 2, 2023
8de468f
pyproject.toml: Ignore missing imports for drivers
bkeryan Oct 2, 2023
706aeb3
service: Add driver-specific create_session(s) APIs for NI-DCPower, N…
bkeryan Oct 3, 2023
03e65ca
tests: Add unit tests for driver submodules
bkeryan Oct 4, 2023
753caf3
service: Update docs
bkeryan Oct 4, 2023
179bf60
service: Add create_session(s) API for NI-Digital, NI-DMM, and NI-SCOPE
bkeryan Oct 4, 2023
fb7288d
mypy: Enable NumPy plugin
bkeryan Oct 4, 2023
ba5aff1
tests: Refactor new tests
bkeryan Oct 4, 2023
9da62d2
PR workflow: Install extras
bkeryan Oct 4, 2023
3d42c7d
PR workflow: Don't uninstall extras when generating docs
bkeryan Oct 4, 2023
5bece4c
Publish workflow: Install extras when building docs and reuse check_n…
bkeryan Oct 4, 2023
9428f01
Publish workflow: Add comment about check_examples
bkeryan Oct 4, 2023
8148f9d
tests: Fix errors with no extras installed
bkeryan Oct 4, 2023
ed08ae3
service: Fix a copy/paste error caught by unit tests
bkeryan Oct 4, 2023
8f0e364
tests: Add unit tests for nidigital, nidmm, and niscope
bkeryan Oct 4, 2023
7f45738
service: Add error info to create_session(s) docstrings
bkeryan Oct 5, 2023
0239261
service: Update new session count errors to say "reserved sessions"
bkeryan Oct 5, 2023
e577936
service: Remove id_query parameter
bkeryan Oct 5, 2023
ed28aa7
Merge remote-tracking branch 'origin/main' into users/bkeryan/create-…
bkeryan Oct 5, 2023
9b46f14
pyproject.toml: Include multiple NumPy versions in poetry.lock
bkeryan Oct 5, 2023
51f02c6
Update poetry.lock
bkeryan Oct 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions .github/workflows/Publish_NIMS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ env:
PYTHON_VERSION: 3.9

jobs:
check_nims:
name: Check NIMS
uses: ./.github/workflows/check_nims.yml
check_nimg:
name: Check NIMG
uses: ./.github/workflows/check_nimg.yml
# Don't run check_examples.yml because the examples may reference a
# package version that doesn't exist yet.
build:
name: Update API reference docs and Publish NIMS Package to PyPI
runs-on : ubuntu-latest
Expand All @@ -32,16 +40,6 @@ jobs:
path: ~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }}

- name: Setup NIMS
run: poetry install

- name: Setup NIMG
run: poetry install
working-directory: ./ni_measurementlink_generator

- name: Lint NIMS, NIMG, and examples
run: poetry run ni-python-styleguide lint

# If the tag is 0.1.0, this will set the version of NIMS package to 0.1.0
- name: Store version from Tag
id: vars
Expand All @@ -56,17 +54,17 @@ jobs:
poetry version ${{ steps.vars.outputs.tag }}
working-directory: ./ni_measurementlink_generator

- name: Setup NIMS with docs
run: poetry install --with docs
- name: Install ni-measurementlink-service (all extras, docs)
run: poetry install -v --all-extras --with docs

- name: Update API Reference Documents(Generated using Sphinx)
- name: Build docs
run: |
rm -rf docs
mkdir -p docs
touch docs/.nojekyll
poetry run sphinx-build _docs_source docs -b html

- name: Commit file changes.
- name: Commit file changes
if: ${{ startsWith(github.event.release.target_commitish, 'main') || startsWith(github.event.release.target_commitish, 'releases/') }}
run: |
git config --local user.email "action@github.com"
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/check_nims.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ jobs:
with:
path: ~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }}
- name: Install ni-measurementlink-service
run: poetry install -v
- name: Install ni-measurementlink-service (all extras)
run: poetry install -v --all-extras
- name: Lint ni-measurementlink-service
run: poetry run ni-python-styleguide lint
- name: Mypy static analysis (ni-measurementlink-service, Linux)
Expand All @@ -42,8 +42,8 @@ jobs:
run: poetry run mypy tests
- name: Mypy static analysis (tests, Windows)
run: poetry run mypy tests --platform win32
- name: Install ni-measurementlink-service with docs
run: poetry install --with docs
- name: Install ni-measurementlink-service (all extras, docs)
run: poetry install -v --all-extras --with docs
- name: Build docs and check for errors/warnings
run: |
rm -rf docs
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ jobs:
with:
path: ~/.cache/pypoetry/virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }}
- name: Install ni-measurementlink-service
- name: Install ni-measurementlink-service (no extras)
run: poetry install -v
- name: Run tests and code coverage (ni-measurementlink-service)
run: poetry run pytest ./tests -v --cov=ni_measurementlink_service --junitxml=test_results/nims-${{ matrix.os }}-py${{ matrix.python-version}}.xml
- name: Run tests and code coverage (ni-measurementlink-service, no extras)
run: poetry run pytest ./tests -v --cov=ni_measurementlink_service --junitxml=test_results/nims-${{ matrix.os }}-py${{ matrix.python-version}}-no-extras.xml
- name: Install ni-measurementlink-service (all extras)
run: poetry install -v --all-extras
- name: Run tests and code coverage (ni-measurementlink-service, all extras)
run: poetry run pytest ./tests -v --cov=ni_measurementlink_service --junitxml=test_results/nims-${{ matrix.os }}-py${{ matrix.python-version}}-all-extras.xml
- name: Install ni-measurementlink-generator
run: poetry install -v
working-directory: ./ni_measurementlink_generator
Expand Down
57 changes: 57 additions & 0 deletions ni_measurementlink_service/_drivers/_nidcpower.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from __future__ import annotations

from typing import Any, Dict, Optional

import nidcpower

from ni_measurementlink_service import session_management # circular import
bkeryan marked this conversation as resolved.
Show resolved Hide resolved
from ni_measurementlink_service._channelpool import GrpcChannelPool
from ni_measurementlink_service._configuration import NIDCPOWER_OPTIONS
from ni_measurementlink_service._drivers._grpcdevice import (
get_insecure_grpc_device_channel,
)
from ni_measurementlink_service._internal.discovery_client import DiscoveryClient
from ni_measurementlink_service._sessiontypes import SessionInitializationBehavior

_INITIALIZATION_BEHAVIOR = {
SessionInitializationBehavior.AUTO: nidcpower.SessionInitializationBehavior.AUTO,
SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidcpower.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidcpower.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
}


class SessionConstructor:
"""Constructs sessions based on SessionInformation."""

def __init__(
self,
discovery_client: DiscoveryClient,
grpc_channel_pool: GrpcChannelPool,
reset: bool,
options: Optional[Dict[str, Any]],
initialization_behavior: SessionInitializationBehavior,
) -> None:
"""Initialize the session constructor."""
self._grpc_channel = get_insecure_grpc_device_channel(
discovery_client, grpc_channel_pool, nidcpower.GRPC_SERVICE_INTERFACE_NAME
)
self._reset = reset
self._options = NIDCPOWER_OPTIONS.to_dict() if options is None else options
self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]

def __call__(self, session_info: session_management.SessionInformation) -> nidcpower.Session:
"""Construct a session object."""
kwargs: Dict[str, Any] = {}
if self._grpc_channel:
kwargs["grpc_options"] = nidcpower.GrpcSessionOptions(
grpc_channel=self._grpc_channel,
session_name=session_info.session_name,
initialization_behavior=self._initialization_behavior,
)

return nidcpower.Session(
resource_name=session_info.resource_name,
reset=self._reset,
options=self._options,
**kwargs,
)
60 changes: 60 additions & 0 deletions ni_measurementlink_service/_drivers/_nidigital.py
bkeryan marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from __future__ import annotations

from typing import Any, Dict, Optional

import nidigital

from ni_measurementlink_service import session_management # circular import
from ni_measurementlink_service._channelpool import GrpcChannelPool
from ni_measurementlink_service._configuration import NIDIGITAL_OPTIONS
from ni_measurementlink_service._drivers._grpcdevice import (
get_insecure_grpc_device_channel,
)
from ni_measurementlink_service._internal.discovery_client import DiscoveryClient
from ni_measurementlink_service._sessiontypes import SessionInitializationBehavior

_INITIALIZATION_BEHAVIOR = {
SessionInitializationBehavior.AUTO: nidigital.SessionInitializationBehavior.AUTO,
SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidigital.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidigital.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
}


class SessionConstructor:
"""Constructs sessions based on SessionInformation."""

def __init__(
self,
discovery_client: DiscoveryClient,
grpc_channel_pool: GrpcChannelPool,
id_query: bool,
reset_device: bool,
options: Optional[Dict[str, Any]],
initialization_behavior: SessionInitializationBehavior,
) -> None:
"""Initialize the session constructor."""
self._grpc_channel = get_insecure_grpc_device_channel(
discovery_client, grpc_channel_pool, nidigital.GRPC_SERVICE_INTERFACE_NAME
)
self._id_query = id_query
self._reset_device = reset_device
self._options = NIDIGITAL_OPTIONS.to_dict() if options is None else options
self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]

def __call__(self, session_info: session_management.SessionInformation) -> nidigital.Session:
"""Construct a session object."""
kwargs: Dict[str, Any] = {}
if self._grpc_channel:
kwargs["grpc_options"] = nidigital.GrpcSessionOptions(
grpc_channel=self._grpc_channel,
session_name=session_info.session_name,
initialization_behavior=self._initialization_behavior,
)

return nidigital.Session(
resource_name=session_info.resource_name,
id_query=self._id_query,
reset_device=self._reset_device,
options=self._options,
**kwargs,
)
60 changes: 60 additions & 0 deletions ni_measurementlink_service/_drivers/_nidmm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from __future__ import annotations

from typing import Any, Dict, Optional

import nidmm

from ni_measurementlink_service import session_management # circular import
from ni_measurementlink_service._channelpool import GrpcChannelPool
from ni_measurementlink_service._configuration import NIDMM_OPTIONS
from ni_measurementlink_service._drivers._grpcdevice import (
get_insecure_grpc_device_channel,
)
from ni_measurementlink_service._internal.discovery_client import DiscoveryClient
from ni_measurementlink_service._sessiontypes import SessionInitializationBehavior

_INITIALIZATION_BEHAVIOR = {
SessionInitializationBehavior.AUTO: nidmm.SessionInitializationBehavior.AUTO,
SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nidmm.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nidmm.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
}


class SessionConstructor:
"""Constructs sessions based on SessionInformation."""

def __init__(
self,
discovery_client: DiscoveryClient,
grpc_channel_pool: GrpcChannelPool,
id_query: bool,
reset_device: bool,
options: Optional[Dict[str, Any]],
initialization_behavior: SessionInitializationBehavior,
) -> None:
"""Initialize the session constructor."""
self._grpc_channel = get_insecure_grpc_device_channel(
discovery_client, grpc_channel_pool, nidmm.GRPC_SERVICE_INTERFACE_NAME
)
self._id_query = id_query
self._reset_device = reset_device
self._options = NIDMM_OPTIONS.to_dict() if options is None else options
self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]

def __call__(self, session_info: session_management.SessionInformation) -> nidmm.Session:
"""Construct a session object."""
kwargs: Dict[str, Any] = {}
if self._grpc_channel:
kwargs["grpc_options"] = nidmm.GrpcSessionOptions(
grpc_channel=self._grpc_channel,
session_name=session_info.session_name,
initialization_behavior=self._initialization_behavior,
)

return nidmm.Session(
resource_name=session_info.resource_name,
id_query=self._id_query,
reset_device=self._reset_device,
options=self._options,
**kwargs,
)
57 changes: 57 additions & 0 deletions ni_measurementlink_service/_drivers/_nifgen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from __future__ import annotations

from typing import Any, Dict, Optional

import nifgen

from ni_measurementlink_service import session_management # circular import
from ni_measurementlink_service._channelpool import GrpcChannelPool
from ni_measurementlink_service._configuration import NIFGEN_OPTIONS
from ni_measurementlink_service._drivers._grpcdevice import (
get_insecure_grpc_device_channel,
)
from ni_measurementlink_service._internal.discovery_client import DiscoveryClient
from ni_measurementlink_service._sessiontypes import SessionInitializationBehavior

_INITIALIZATION_BEHAVIOR = {
SessionInitializationBehavior.AUTO: nifgen.SessionInitializationBehavior.AUTO,
SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: nifgen.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: nifgen.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
}


class SessionConstructor:
"""Constructs sessions based on SessionInformation."""

def __init__(
self,
discovery_client: DiscoveryClient,
grpc_channel_pool: GrpcChannelPool,
reset_device: bool,
options: Optional[Dict[str, Any]],
initialization_behavior: SessionInitializationBehavior,
) -> None:
"""Initialize the session constructor."""
self._grpc_channel = get_insecure_grpc_device_channel(
discovery_client, grpc_channel_pool, nifgen.GRPC_SERVICE_INTERFACE_NAME
)
self._reset_device = reset_device
self._options = NIFGEN_OPTIONS.to_dict() if options is None else options
self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]

def __call__(self, session_info: session_management.SessionInformation) -> nifgen.Session:
"""Construct a session object."""
kwargs: Dict[str, Any] = {}
if self._grpc_channel:
kwargs["grpc_options"] = nifgen.GrpcSessionOptions(
grpc_channel=self._grpc_channel,
session_name=session_info.session_name,
initialization_behavior=self._initialization_behavior,
)

return nifgen.Session(
resource_name=session_info.resource_name,
reset_device=self._reset_device,
options=self._options,
**kwargs,
)
60 changes: 60 additions & 0 deletions ni_measurementlink_service/_drivers/_niscope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from __future__ import annotations

from typing import Any, Dict, Optional

import niscope

from ni_measurementlink_service import session_management # circular import
from ni_measurementlink_service._channelpool import GrpcChannelPool
from ni_measurementlink_service._configuration import NISCOPE_OPTIONS
from ni_measurementlink_service._drivers._grpcdevice import (
get_insecure_grpc_device_channel,
)
from ni_measurementlink_service._internal.discovery_client import DiscoveryClient
from ni_measurementlink_service._sessiontypes import SessionInitializationBehavior

_INITIALIZATION_BEHAVIOR = {
SessionInitializationBehavior.AUTO: niscope.SessionInitializationBehavior.AUTO,
SessionInitializationBehavior.INITIALIZE_SERVER_SESSION: niscope.SessionInitializationBehavior.INITIALIZE_SERVER_SESSION,
SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION: niscope.SessionInitializationBehavior.ATTACH_TO_SERVER_SESSION,
}


class SessionConstructor:
"""Constructs sessions based on SessionInformation."""

def __init__(
self,
discovery_client: DiscoveryClient,
grpc_channel_pool: GrpcChannelPool,
id_query: bool,
reset_device: bool,
options: Optional[Dict[str, Any]],
initialization_behavior: SessionInitializationBehavior,
) -> None:
"""Initialize the session constructor."""
self._grpc_channel = get_insecure_grpc_device_channel(
discovery_client, grpc_channel_pool, niscope.GRPC_SERVICE_INTERFACE_NAME
)
self._id_query = id_query
self._reset_device = reset_device
self._options = NISCOPE_OPTIONS.to_dict() if options is None else options
self._initialization_behavior = _INITIALIZATION_BEHAVIOR[initialization_behavior]

def __call__(self, session_info: session_management.SessionInformation) -> niscope.Session:
"""Construct a session object."""
kwargs: Dict[str, Any] = {}
if self._grpc_channel:
kwargs["grpc_options"] = niscope.GrpcSessionOptions(
grpc_channel=self._grpc_channel,
session_name=session_info.session_name,
initialization_behavior=self._initialization_behavior,
)

return niscope.Session(
resource_name=session_info.resource_name,
id_query=self._id_query,
reset_device=self._reset_device,
options=self._options,
**kwargs,
)
Loading
Loading