Getting Started

Learn the basic concepts required to automate FlexLogger tests using the Python API.

Prerequisites

Before using the FlexLogger Python API, complete the following tasks.
  • Install FlexLogger 2022 Q2 or later and create a FlexLogger project with one or more input channels.

  • Enable the Automation server preference in FlexLogger. In FlexLogger, navigate to File>>Preferences and check Enable FlexLogger to receive remote automation commands in the Automation server section of the General tab.

  • Download and install Python 3.6 or later from python.org/downloads. For more information on installing and using Python, refer to the Python documentation on docs.python.org. During installation, enable Add Python to PATH so you can execute Python commands more easily.

  • Install the FlexLogger Automation Python module, niflexlogger-automation, using the method described below or one of the methods described in the Readme.

If you are new to Python, start by creating and running your first script. If you an experienced Python user, refer to the examples and API reference.

Installing the FlexLogger Automation Python module

Install the FlexLogger Automation Python module so you can control FlexLogger tests programatically.

  1. Open the command prompt.

  2. Execute the following command to install the module.

    pip install niflexlogger-automation

Creating and running your first script

Use the Start and Stop a Test example code to automate a FlexLogger test. The steps below describe how to perform this task with a text editor and the command prompt. You can also use your favorite integrated development environment (IDE).

  1. Close FlexLogger if it is running.

  2. Open a text editor.

  3. Copy and paste the code provided below.

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger and open a project."""
 9    # Note that using the "with" statement here means that when the block
10    # goes out of scope, the application will be closed.  To prevent this,
11    # call app.disconnect() before the scope ends.
12    with Application.launch() as app:
13        versions = app.get_version()
14        print("FlexLogger version: " + versions[1])
15        project = app.open_project(path=project_path, timeout=180)
16        print("Press Enter to close project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))
  1. Save the file with a .py extension. For example, my_script.py. Enclose file paths in quotation marks if you have spaces in your folder or file names.

  2. Open the command prompt as an administrator.

  3. Change the directory to the location where you saved your script. For example,

    cd C:\Users\Desktop

  4. Run the script with the python command. The Start and Stop a Test example requires that you provide the path to the project you want to control as an input. Use quotation marks when specifying the path. For example,

    python my_script.py "C:\Users\Desktop\my_FlexLogger_Project.flxproj"

    The Python script launches FlexLogger, opens the project you specified, and starts running a test. The command prompt displays a status message and provides you with the option to stop the test and close the project.

Examples

Communicating with FlexLogger

Launch FlexLogger and open a project

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger and open a project."""
 9    # Note that using the "with" statement here means that when the block
10    # goes out of scope, the application will be closed.  To prevent this,
11    # call app.disconnect() before the scope ends.
12    with Application.launch() as app:
13        versions = app.get_version()
14        print("FlexLogger version: " + versions[1])
15        project = app.open_project(path=project_path, timeout=180)
16        print("Press Enter to close project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))

Connect to FlexLogger when it is already running

 1import sys
 2
 3from flexlogger.automation import Application
 4
 5
 6def main():
 7    """Connect to an already running instance of FlexLogger with an open project
 8
 9    Note that before connecting to an already running instance of FlexLogger,
10    the Automation server preference must be enabled. You can enable this preference by opening the
11    "File>>Preferences" menu item, and then enabling the "Automation server" preference in the
12    "General" tab.
13    """
14    app = Application()
15    project = app.get_active_project()
16    if project is None:
17        print("No project is open in FlexLogger!")
18        return 1
19    test_session_state = project.test_session.state
20    print("The test session state is:")
21    print(test_session_state)
22    print("Press Enter to disconnect from FlexLogger...")
23    input()
24    app.disconnect()
25    return 0
26
27
28if __name__ == "__main__":
29    sys.exit(main())

Test session

Start and stop a test

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, start and stop the test session."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        test_session = project.test_session
12        test_session.start()
13        print("Test started. Press Enter to stop the test and close the project...")
14        input()
15        test_session.stop()
16        project.close()
17    return 0
18
19
20if __name__ == "__main__":
21    argv = sys.argv
22    if len(argv) < 2:
23        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
24        sys.exit()
25    project_path_arg = argv[1]
26    sys.exit(main(project_path_arg))

Adding a note to a log file

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, start the test session and add a note."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        test_session = project.test_session
12        test_session.start()
13        note = input("Test started. Enter a note to log: ")
14        test_session.add_note(note)
15        print("Note added. Press Enter to stop the test and close the project...")
16        input()
17
18        test_session.stop()
19        project.close()
20    return 0
21
22
23if __name__ == "__main__":
24    argv = sys.argv
25    if len(argv) < 2:
26        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
27        sys.exit()
28    project_path_arg = argv[1]
29    sys.exit(main(project_path_arg))

Channels

Getting the value of a channel

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and get the value of a channel."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        channel_name = input("Enter the name of the channel to get the value of: ")
12        channel_specification = project.open_channel_specification_document()
13        channel_value = channel_specification.get_channel_value(channel_name)
14        print("Channel value:")
15        print(channel_value)
16        print("Press Enter to close the project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))

Setting the value of a channel

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and sets the value of a channel."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        channel_name = input("Enter the name of the channel to set the value of: ")
12        channel_value = input("Enter the new channel value: ")
13        channel_specification = project.open_channel_specification_document()
14        channel_specification.set_channel_value(channel_name, float(channel_value))
15        print("Channel value set. Press Enter to close the project...")
16        input()
17        project.close()
18    return 0
19
20
21if __name__ == "__main__":
22    argv = sys.argv
23    if len(argv) < 2:
24        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
25        sys.exit()
26    project_path_arg = argv[1]
27    sys.exit(main(project_path_arg))

Logging

Getting the log file base path and name

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and gets the log file base path and name."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        logging_specification = project.open_logging_specification_document()
12        log_file_base_path = logging_specification.get_log_file_base_path()
13        log_file_name = logging_specification.get_log_file_name()
14        print("Log file base path: " + log_file_base_path)
15        print("Log file name: " + log_file_name)
16        print("Press Enter to close the project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))

Setting the log file base path and name

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and sets the log file base path and name."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        log_file_base_path = input("Enter the log file base path: ")
12        log_file_name = input("Enter the log file name: ")
13        logging_specification = project.open_logging_specification_document()
14        logging_specification.set_log_file_base_path(log_file_base_path)
15        logging_specification.set_log_file_name(log_file_name)
16        print("Log file base path and name set. Press Enter to close the project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))

Getting a test property

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and gets the value of a test property."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        test_property_name = input("Enter the name of the test property to get the value of: ")
12        logging_specification = project.open_logging_specification_document()
13        test_property = logging_specification.get_test_property(test_property_name)
14        print("Test property:")
15        print(test_property)
16        print("Press Enter to close the project...")
17        input()
18        project.close()
19    return 0
20
21
22if __name__ == "__main__":
23    argv = sys.argv
24    if len(argv) < 2:
25        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
26        sys.exit()
27    project_path_arg = argv[1]
28    sys.exit(main(project_path_arg))

Setting a test property

 1import os
 2import sys
 3
 4from flexlogger.automation import Application
 5
 6
 7def main(project_path):
 8    """Launch FlexLogger, open a project, and sets the value of a test property."""
 9    with Application.launch() as app:
10        project = app.open_project(path=project_path)
11        test_property_name = input("Enter the name of the test property to set the value of: ")
12        test_property_value = input("Enter the test property value: ")
13        logging_specification = project.open_logging_specification_document()
14        logging_specification.set_test_property(test_property_name, test_property_value)
15        print("Test property set. Press Enter to close the project...")
16        input()
17        project.close()
18    return 0
19
20
21if __name__ == "__main__":
22    argv = sys.argv
23    if len(argv) < 2:
24        print("Usage: %s <path of project to open>" % os.path.basename(__file__))
25        sys.exit()
26    project_path_arg = argv[1]
27    sys.exit(main(project_path_arg))

Troubleshooting

Can’t connect to running FlexLogger

If you get an error connecting to an already running instance of FlexLogger, the Automation server preference may not be enabled. You can enable this preference by opening the “File>>Preferences” menu item, and then enabling the “Automation server” preference in the “General” tab.

_images/preference_automation_server.png

Exception on first call into FlexLogger

If you see an exception on the first call into FlexLogger similar to:

grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
      status = StatusCode.UNAVAILABLE
      details = "failed to connect to all addresses"
      debug_error_string = "{"created":"@1608052709.612000000","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":4143,"referenced_errors":[{"created":"@1608052633.077000000","description":"failed to connect to all addresses","file":"src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc","file_line":398,"grpc_status":14}]}"

the problem may be an HTTP proxy. To test this, in your Python script add the following lines before your FlexLogger API calls:

if os.environ.get('https_proxy'):
   del os.environ['https_proxy']
if os.environ.get('http_proxy'):
   del os.environ['http_proxy']

If this fixes the problem, try configuring your proxy to not affect traffic to localhost. See this GitHub issue for an example.