Skip to content

Commit

Permalink
Merge pull request #38 from ni/v0_1_9_add_get_version
Browse files Browse the repository at this point in the history
Add get_version function to retrieve the version of FlexLogger the API connects to.
  • Loading branch information
ccaltagi authored Jan 24, 2024
2 parents f9320b2 + acb75bb commit 69b8536
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Requirements
============
**niflexlogger-automation** has the following requirements:

* FlexLogger 2023 Q4+
* FlexLogger 2024 Q1+
* CPython 3.6 - 3.10. If you do not have Python installed on your computer, go to python.org/downloads to download and install it.

.. _installation_section:
Expand Down
2 changes: 2 additions & 0 deletions examples/Basic/launch_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def main(project_path):
# goes out of scope, the application will be closed. To prevent this,
# call app.disconnect() before the scope ends.
with Application.launch() as app:
versions = app.get_version()
print("FlexLogger version: " + versions[1])
project = app.open_project(path=project_path, timeout=180)
print("Press Enter to close project...")
input()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
package national_instruments.flex_logger.automation.protocols;

import "DiagramSdk/Automation/DiagramSdk.Automation.Protocols/Identifiers.proto";
import "google/protobuf/empty.proto";

// Service interface for the server application.
service FlexLoggerApplication {
// RPC call to open an existing project on the server.
rpc OpenProject(OpenProjectRequest) returns (OpenProjectResponse) {}
// RPC call to get the currently active (open) project from the server.
rpc GetActiveProject(GetActiveProjectRequest) returns (GetActiveProjectResponse) {}
// RPC call to get the FlexLogger version from the server.
rpc GetVersion(google.protobuf.Empty) returns (GetVersionResponse) {}
}

// Information necessary to open an existing Project.
Expand All @@ -35,4 +38,12 @@ message GetActiveProjectResponse {
bool active_project_available = 1;
// The id of the active project. Should not be used if active_project_available is false.
national_instruments.diagram_sdk.automation.protocols.ProjectIdentifier project = 2;
}
}

// Response object for the get version request.
message GetVersionResponse {
// The numeric internal version (24.0.0.0)
string version = 1;
// The string version contaning the year and quarter (2024 Q1)
string version_string = 2;
}
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def _get_version(name: str) -> str:
script_dir = os.path.dirname(os.path.realpath(__file__))
script_dir = os.path.join(script_dir, name)
if not os.path.exists(os.path.join(script_dir, "VERSION")):
version = "0.1.8"
version = "0.1.9"
else:
with open(os.path.join(script_dir, "VERSION"), "r") as version_file:
version = version_file.read().rstrip()
Expand Down
24 changes: 24 additions & 0 deletions src/flexlogger/automation/_application.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from google.protobuf import empty_pb2
import mmap
import os
import re
Expand Down Expand Up @@ -258,6 +259,29 @@ def get_active_project(self) -> Optional[Project]:
self._raise_exception_if_closed()
raise FlexLoggerError("Failed to get the active project") from rpc_error

def get_version(self) -> (str, str):
"""Gets the FlexLogger server version.
Returns:
A tuple containing the FlexLogger versions (internal version and user visible version).
Raises:
FlexLoggerError: if getting the version fails.
"""
try:
stub = FlexLoggerApplication_pb2_grpc.FlexLoggerApplicationStub(self._channel)
response = stub.GetVersion(empty_pb2.Empty())
return response.version, response.version_string
# For most methods, catching ValueError is sufficient to detect whether the Application
# has been closed, and avoids race conditions where another thread closes the Application
# in the middle of the first thread's call.
#
# This method passes self._channel directly to a stub, and this raises an AttributeError
# if self._channel is None, so catch this as well.
except (RpcError, ValueError, AttributeError) as rpc_error:
self._raise_exception_if_closed()
raise FlexLoggerError("Failed to get version") from rpc_error

@classmethod
def _launch_flexlogger(cls, timeout_in_seconds: float, path: Optional[Path] = None) -> int:
import win32api # type: ignore
Expand Down
2 changes: 2 additions & 0 deletions src/flexlogger/automation/_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ def save(self) -> None:
Raises:
FlexLoggerError: if saving the project fails due to a communication error.
If there is no communication error with the FlexLogger application, this function will not raise an
exception, but instead return a boolean indicating if the project was properly saved.
"""
stub = Project_pb2_grpc.ProjectStub(self._channel)
try:
Expand Down
14 changes: 14 additions & 0 deletions tests/test_application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from flexlogger.automation import Application
import pytest # type: ignore
import re


class TestApplication:
@pytest.mark.integration # type: ignore
def test__launch_flexLogger__get_versions__versions_match_pattern(self, app: Application) -> None:
version, version_string = app.get_version()

version_pattern = re.compile(r"2\d.\d.\d.\d")
assert version_pattern.match(version)
version_string_pattern = re.compile(r"20\d\d Q\d")
assert version_string_pattern.match(version_string)

0 comments on commit 69b8536

Please sign in to comment.