-
Notifications
You must be signed in to change notification settings - Fork 51
Creating a gRPC Client
Each supported driver API has a corresponding .proto
file in a sub-folder containing the driver name. All driver sub-folders are located under the generated
folder here. The .proto
file describes the API used by clients to interact with the ni_grpc_device_server
and the NI device(s) connected to the server. For example, the .proto
file for NI-SCOPE can be found (here). There is an additional .proto
file that describes the Session Utilities API.
The information in the remainder of this document applies to creating a gRPC client in Python but gRPC also supports writing clients in additional languages. In order to create a client in languages other than Python:
- See the gRPC documentation for a full list of supported languages.
- Refer to this section of the Protocol Buffers documentation to learn how to generate the code needed to work with the desired API's messages as defined in each
.proto
file. - Navigate to the client section of the relevant Basics Tutorial for more details on writing client code in a given language. An example in C++ can be found here
Refer to this video or the below steps for creating gRPC application using python.
-
Install the
grpcio-tools
using your preferred Python package manager. Two options are outlined below:PIP
> pip install grpcio-tools
Anaconda
> conda install grpcio-tools
-
(optional) Install
mypy-protobuf
,types-protobuf
, andgrpc-stubs
to enable PEP 484 type hints for gRPC and Protocol Buffers. This enables text editors such as VS Code to more accurately auto-complete references to gRPC stub and message objects. Type hints are also a prerequisite for using static type checking tools such asmypy
andpyright
.> pip install mypy-protobuf types-protobuf grpc-stubs
-
Determine whether to use the standard proto compiler or the Better Protobuf compiler to generate the supporting files from each
.proto
file. The latter produces a more idiomatic version of the gRPC API. For more information refer to the Better Protobuf repository here. If using the Better Protobuf compiler then install thebetterproto
tools, otherwise skip to the next step:> pip install "betterproto[compiler]"
Note: The Better Protobuf compiler has a bug generating helpers for gRPC messages with
oneof
types. The problem is that zero-value messages in aoneof
group take priority based on order and overwrite other set values. Therefore, only the last field, the field that has '_raw` appended to the name, can be properly set without wrapper modification. -
Generate the supporting files for each API required by the client:
Example commands ran from directory containing example file as organized in the client release
a. Standard compiler:
> python -m grpc_tools.protoc -I="..\..\proto" --python_out=. --grpc_python_out=. session.proto nidevice.proto niscope.proto
Output for NI-SCOPE will be
session_pb2.py
,session_pb2_grpc.py
,nidevice_pb2.py
,nidevice_pb2_grpc.py
,niscope_pb2.py
, andniscope_pb2_grpc.py
.b. Standard compiler with type hints:
> python -m grpc_tools.protoc -I="..\..\proto" --python_out=. --grpc_python_out=. --mypy_out=. --mypy_grpc_out=. session.proto nidevice.proto niscope.proto
Output for NI-SCOPE will be
session_pb2.py
,session_pb2_grpc.py
,nidevice_pb2.py
,nidevice_pb2_grpc.py
,niscope_pb2.py
, andniscope_pb2_grpc.py
, plus the corresponding.pyi
files containing the type hints.c. Better Protobuf compiler:
> mkdir nidevice > cd nidevice > python -m grpc_tools.protoc -I="..\..\..\proto" --python_betterproto_out=. session.proto nidevice.proto niscope.proto
Output for NI-SCOPE will be
__init__.py
,niscope_pb2_grpc.py
,nidevice_pb2_grpc.py
,session_pb2_grpc.py
, and agrpc
folder.The directory containing the proto file being used as well as path(s) to any imports must be specified using the
-I
flag. The examples above demonstrate generation on Windows but you can adjust the path delimiters as needed for the platform being used. -
Copy the output files (and folder) from the Step 3 to the folder containing the python client.
-
Add module imports:
a. Standard compiler:
import grpc import niscope_pb2 as niscope_types import niscope_pb2_grpc as grpc_niscope
b. Better Protobuf compiler:
import asyncio from nidevice import niscope_grpc from grpclib.client import Channel
Note Install and import other libraries like matplotlib as required.
-
Create a secure or insecure channel based on the server's security configuration. Refer to this wiki page for details.
-
Write API specific calls to get data from your device. Refer to examples here.
- Windows: .NET Framework 4.5+, Visual Studio 2013 or higher
-
Open Visual Studio
- Create a new project/solution
- Select Class Library(.NET Framework) for the first project.
- In this example, we'll name the solution NIDCPower and the project NIDCPowerProto.
-
Add the Grpc and Google.Protobuf NuGet packages as dependencies of this NIDCPowerProto project
- Right click on project
- Manage NuGet Packages
- Install these packages using Browse option
-
Add the Grpc.Tools NuGet package (version should be >= 1.17) to your project. This package enables you to generate code from the Protocol Buffer (.proto) files as part of the build.
-
Add session.proto and nidcpower.proto files directly under the NIDCPowerProto project. Then Save All (Ctrl+ Shift + S) so that NIDCPowerProto.csproj gets updated.
Note: Proto files must be directly under this project. Placing them in other locations in the project may result in build errors due to the use of relative paths by Grpc.Tools.
-
Open the NIDCPowerProto.csproj file in a plain text editor such as Notepad and mark the proto files Protobuf as shown below:
<Protobuf Include="nidcpower.proto" /> <Protobuf Include="session.proto" />
-
Reload the project. Go to the Properties panel of those proto files and confirm that
Build Action
is listed as Protobuf: -
Build the NIDCPowerProto project.
-
Build should create NIDCPowerProto.dll in the bin\Debug folder.
-
Build should also create the following 4 highlighted files(shown in image below) in obj\Debug folder. These are the gRPC generated files by Grpc.Tools NuGet package.
-
-
Create a new Console App (.NET Framework) within the solution to set up the gRPC client. In this example, we'll name the app NIDCPowerClient.
-
Right-click on the NIDCPowerClient project in the solution explorer and select Add -> Reference -> NIDCPowerProto project -> OK.
-
Right-click on the NIDCPowerClient project again and select Manage NuGet Packages -> Install Using Browse to add the Grpc and Google.Protobuf NuGet packages as project dependencies.
-
Copy the client code below into Program.cs:
using System; using Grpc.Core; using NationalInstruments.Grpc.DCPower; namespace NIDCPowerClient { class Program { public static void Main(string[] args) { var server_address = "localhost"; var server_port = "31763"; var session_name = "NI-DCPower-Session"; // Resource name, channel name, and options for a simulated 4147 client. var resource = "SimulatedDCPower"; var options = "Simulate=1,DriverSetup=Model:4147;BoardType:PXIe"; var channels = "0"; Channel channel = new Channel(server_address + ":" + server_port, ChannelCredentials.Insecure); var client = new NiDCPower.NiDCPowerClient(channel); var initialize_reply = client.InitializeWithChannels(new InitializeWithChannelsRequest { SessionName = session_name, ResourceName = resource, Channels = channels, Reset = false, OptionString = options }); var vi = initialize_reply.Vi; if (initialize_reply.Status == 0) { Console.WriteLine("Initialization was successful."); } else { Console.WriteLine($"Initialization was not successful. Status is {initialize_reply.Status}"); } client.Close(new CloseRequest { Vi = vi }); channel.ShutdownAsync().Wait(); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } }
-
Build the NIDCPowerClient project. Check the
bin\Debug
folder to make sure the build generated theNIDCPowerClient.exe
app. -
Run the ni_grpc_device_server obtained from our release on the server machine in one terminal.
-
Run the NIDCPowerClient.exe obtained in step 12 in another terminal.
- https://grpc.io/docs/languages/csharp/quickstart/
- https://github.com/grpc/grpc/tree/v1.38.0/examples/csharp/HelloworldLegacyCsproj
- https://github.com/grpc/grpc/blob/master/src/csharp/BUILD-INTEGRATION.md
- https://github.com/grpc/grpc/blob/v1.38.0/src/csharp/README.md#prerequisites
- https://codelabs.developers.google.com/codelabs/cloud-grpc-csharp#0
- https://grpc.io/docs/languages/csharp/quickstart/
- https://github.com/grpc/grpc/tree/v1.38.0/examples/csharp/Helloworld
- https://docs.microsoft.com/en-us/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore5.0&tabs=visual-studio#create-the-grpc-client-in-a-net-console-app
- https://www.youtube.com/watch?v=ru5x_hDZ9Qw
The gRPC API is based on the C APIs for each supported driver. See Driver Documentation for finding the right documentation for you. Applications developed against the C APIs can be converted to use the gRPC API taking into account the following considerations:
-
Each of the functions in the C header have a corresponding RPC service method in the
.proto
file.
Example: theniScope_InitWithOptions
function defined inniScope.h
corresponds to theInitWithOptions
method on theNiScope
service inniscope.proto
. -
Each RPC method accepts a
Request
andResponse
protobuf message where the fields of theRequest
correspond to the input parameters of the C function and the fields of theResponse
message correspond to the return value and output parameters in the C function.- Input parameters related to the size of output arrays and strings may be omitted from the request message. For example, the
bufSize
parameter ofniScope_GetAttributeViString
is automatically calculated and is not included in theGetAttributeViStringRequest
message inniscope.proto
. - Initialization functions can accept an additional session name which can be used to enable multiple clients to share a single session to a device.
- Input parameters related to the size of output arrays and strings may be omitted from the request message. For example, the
-
Many of the constants defined in the driver C header file are grouped into enums in the
.proto
file. It is recommended to use these enum values in Request/Response message fields.
For example, if you want the fetch API to calculate timeout automatically, setmaximum_time
parameter to TIME_LIMIT_NIDMM_VAL_TIME_LIMIT_AUTO value since the enum exists.fetch_result = dmm_service.fetch(vi = vi, maximum_time = nidmm_grpc.TimeLimit.TIME_LIMIT_NIDMM_VAL_TIME_LIMIT_AUTO)
-
If enum is not available for the value that you want to pass as a function parameter, use corresponding
<param_name>_raw
parameter for assigning the value directly.
For example, If you want to set the fetch API timeout to 10 milliseconds, since enum corresponding to 10 milliseconds does not exist, you should usemaximum_time_raw
parameter for passing the value.fetch_result = dmm_service.fetch(vi = vi, maximum_time_raw = 10)
NOTE: Better Protobuf compiler does not support setting enum values in the message containing
oneof
types. Use raw parameters in this case. -
For CheckAttribute and SetAttribute APIs, values for attributes of a particular datatype are available under enums associated with that datatype. For example:
NiDMMInt32AttributeValues
enum contains values for NI-DMM attributes of Int32 type.
NiDCPowerReal64AttributeValues
enum contains values for NI-DCPower attributes of Real64 type.NOTE: No enums are available for
GetAttribute
APIs.
-
gRPC has a default limit on max message size. This size can be configured in the client.
For an insecure python client, with unlimited message size:
channel = grpc.insecure_channel(
f"{server_address}:{server_port}",
options=[
("grpc.max_send_message_length", -1),
("grpc.max_receive_message_length", -1),
],
)
For C# see MaxReceiveMessageSize.
Depending on your application/driver, it may be possible to acquire data in smaller chunks.
Creating and Setting Up a gRPC Server
Session Utilities API Reference
gRPC API Differences From C API
Sharing Driver Sessions Between Clients
C API Docs
NI-DAQmx
- gRPC API Differences From C API
- Task Configuration And Control
- Channel Configuration And Creation
- Timing
- Triggering
- Read Functions
- Write Functions
- Export Hardware Signals
- Scale Configuration
- Internal Buffer Configuration
- Advanced Functions
- System Configuration
- Error Handling
- Buffer Attributes
- Calibration Info Attributes
- Channel Attributes
- Device Attributes
- Export Signal Attributes
- Persisted Channel Attributes
- Persisted Scale Attributes
- Persisted Task Attributes
- Physical Channel Attributes
- Read Attributes
- Scale Attributes
- System Attributes
- Task Attributes
- Timing Attributes
- Trigger Attributes
- Watchdog Attributes
- Write Attributes
NI-DCPOWER
- Setup Functions
- Configure Functions
- Measurement Functions
- Control Functions
- Trigger And Event
- Attribute Functions
- Query Functions
- Calibration Functions
- Utility Functions
- Supported Device
- Source Attributes
- Transient Attributes
- Voltage Attributes
- Current Attributes
- Pulse Voltage Attributes
- Pulse Current Attributes
- Cutoff Attributes
- Measurement Attributes
- Trigger Attributes Functions
- Event Attributes
- Advanced Attributes
- Inherent Ivi Attributes
- Supported Device Attributes
NI-DIGITAL PATTERN DRIVER
- Init And Close Functions
- Session Locking Functions
- Utility Functions
- Error Handling Functions
- Calibration Functions
- Attributes Functions
- Pin Map Functions
- Low Level Functions
- Low Level Action Functions
- Pin Control Functions
- Static IO Functions
- Clock Generator Functions
- Levels And Timing Functions
- TDR Functions
- PPMU Configuration Functions
- DC Voltage Functions
- DC Current Functions
- PPMU Action Functions
- Pattern Configuration Functions
- Pattern Action Functions
- History Ram Functions
- Source Memory Functions
- Capture Memory Functions
- Triggers And Events Functions
- Conditional Jump Trigger Functions
- Sequencer Flag Functions
- Sequencer Register Functions
- Match Fail Combination Functions
- Pattern Results Functions
- Sort Results Functions
- Frequency Measurement Functions
- IVI Inherent Attributes
- Specific Driver Information Attributes, Read Only
- Driver Setup Information Attributes
- Device Attributes
- Pin Control Attributes
- Level Configuration Attributes
- Trigger Configuration Attributes
- PPMU Attributes
- Patterns Attributes
- Pattern Opcode Event Attributes
- Timing Offset Attributes
- Keep Alive Attributes
- Frequency Measurement Attributes
- Clock Generator Attributes
- History RAM
- Synchronization Attributes
- TDR Endpoint Termination Attributes
NI-FGEN
- Setup Functions
- Configuration Functions
- Standard Output Functions
- Arbitrary Waveform Output Functions
- Arbitrary Sequence Output Functions
- Incremental Waveform Write Functions
- Configure Clock Functions
- Trigger And Syncronizations Functions
- 5404 Routing Functions
- Script Output Functions
- Configure Onboard Signal Processing Functions
- Configure Peer To Peer Functions
- Attribute Functions
- Waveform Control Functions
- Error Functions
- Output Attributes
- Arbitrary Waveform Attributes
- Data Transfer Attributes
- Onboard Signal Processing Attributes
- Peer To Peer Attributes
- Standard Function Attributes
- Clock Attributes
- Event Attributes
- Triggering Attributes
- Instrument Specific Attributes
- Inherent IVI Attributes
- 5401 5411 5431
NI-RFmx Bluetooth
- gRPC API Differences From C API
- General Functions
- Configuration Functions
- Set And Get Attribute Functions
- Fetch Results Functions
- Utility Functions
- Build String Functions
- Advanced Functions
- General Attributes
- Trigger Attributes
- Packet Attributes
- Auto Detect Signal Attributes
- Modacc Attributes
- ACP Attributes
- Twenty dB Attributes
- Frequency Range Attributes
- TXP Attributes
- Advanced Attributes
NI-RFmx NR
- gRPC API Differences From C API
- General Functions
- Configuration Functions
- Set And Get Attributes Functions
- Fetch Results Functions
- Utility Functions
- Build String Functions
- Advanced Functions
- General Attributes
- Trigger Attributes
- Signal Detection Attributes
- Component Carrier Attributes
- List Attributes
- Modacc Attributes
- ACP Attributes
- CHP Attributes
- OBW Attributes
- SEM Attributes
- TXP Attributes
- Pvt Attributes
- Advanced Attributes
NI-RFmx LTE
- gRPC API Differences From C API
- General Functions
- Configuration Functions
- Ch Configuration Functions
- NB IoT Configuration Functions
- ModAcc Configuration Functions
- ACP Configuration Functions
- CHP Configuration Functions
- OBW Configuration Functions
- SEM Configuration Functions
- PVT Configuration Functions
- SlotPhase Configuration Functions
- SlotPower Configuration Functions
- Set And Get Attribute Functions
- ModAcc Fetch Functions
- ACP Fetch Functions
- CHP Fetch Functions
- OBW Fetch Functions
- SEM Fetch Functions
- PVT Fetch Functions
- SlotPhase Fetch Functions
- SlotPower Fetch Functions
- Utility Functions
- Build String Functions
- Advanced Functions
- General Attributes
- Trigger Attributes
- Component Carrier Attributes
- ModAcc Attributes
- ACP Attributes
- CHP Attributes
- OBW Attributes
- SEM Attributes
- PVT Attributes
- SlotPhase Attributes
- SlotPower Attributes
- Advanced Attributes
NI-RFmx SpecAn
- gRPC API Differences From C API
- General Functions
- Configuration Functions
- Set And Get Attribute Functions
- Read Functions
- Fetch Functions
- Utility Functions
- Marker Functions
- Build String Functions
- Advanced Functions
- General Attributes
- Trigger Attributes
- ACP Attributes
- Cdf Attributes
- CHP Attributes
- Fcnt Attributes
- Harm Attributes
- OBW Attributes
- SEM Attributes
- Spectrum Attributes
- Spur Attributes
- TXP Attributes
- AMPM Attributes
- Dpd Attributes
- IQ Attributes
- IM Attributes
- NF Attributes
- Phasenoise Attributes
- PAVT Attributes
- Advanced Attributes
NI-RFmx WLAN
- gRPC API Differences From C API
- General Functions
- Configuration Functions
- Set And Get Attribute Functions
- Fetch DSSS ModAcc Functions
- Fetch OFDM ModAcc Functions
- Fetch SEM Functions
- Fetch TXP Functions
- Fetch PowerRamp Functions
- Utility Functions
- Build String Functions
- Advanced Functions
- General Attributes
- Trigger Attributes
- OFDM Attributes
- Auto Detect Signal Attributes
- DSSS ModAcc Attributes
- OFDM ModAcc Attributes
- SEM Attributes
- TXP Attributes
- PowerRamp Attributes
- Advanced Attributes
NI-RFSA
- General Functions
- Configuration Functions
- Acquisition Functions
- Utility Functions
- Calibration Functions
- General Attributes
- Vertical Attributes
- Signal Path Attributes
- Acquisition Attributes
- Acquisition Attributes
- Triggers Attributes
- Events Attributes
- Device Characteristics Attributes
- Peer To Peer Streaming Attributes
- Configuration List Attributes
- Inherent IVI Properties Attributes
- De-embedding Attributes
- Self Calibration Attributes
- Factory Calibration Attributes
- External Alignment Attributes
- Device Specific Attributes
NI-RFSG
- General Functions
- Generation Configuration
- Utility Functions
- Calibration Functions
- Arb Attributes
- Clock Attributes
- Configuration List Attributes
- De-embedding Attributes
- Device Characteristics Attributes
- Device Specific Attributes
- Events Attributes
- External Calibration Attributes
- Inherent IVI Attributes Attributes
- IQ Impairment Attributes
- Load Configurations Attributes
- Modulation Attributes
- Obsolete Attributes
- Peer To Peer Attributes
- RF Attributes
- Self Calibration Attributes
- Triggers Attributes
NI-SCOPE
- Setup Functions
- Configure Functions
- Attribute Functions
- Acquisition Functions
- Measurement Functions
- Calibrate Functions
- Utility Funcitons
- Error Handling Functions
- IVI Compliance Or Obsolete Functions
- Vertical Attributes
- Horizontal Attributes
- Trigger Attributes
- Clocking Attributes
- Synchronization Attributes
- Acquisition Attributes
- Waveform Measurements Attributes
- Onboard Signal Processing Attributes
- Peer To Peer Streaming Attributes
- Device Attributes
- IVI Or Obsolete Attributes
- Instrument Capabilities Attributes
- If Digitizer Attributes
NI-XNET
- gRPC API differences from C APIs
- General Functions
- Cluster Properties
- Database Properties
- Device Properties
- ECU Properties
- Frame Properties
- Interface Properties
- LIN Schedule Entry Properties
- LIN Schedule Properties
- PDU Properties
- Session Ethernet Properties
- Session Frame Properties
- Session Interface Properties
- Session Properties
- Session SAE J1939 Properties
- Signal Properties
- Subframe Properties
- System Properties
- IP-Stack Functions
- Socket Options
- Socket Functions