Clients in a New Programming Language#

All Riva Speech AI Skills described in this section are exposed using gRPC to maximize compatibility with existing software infrastructure and ease of integration. gRPC officially supports 12 languages, including C++, Java, Python, and Golang, with unofficial support for many others.

The gRPC services and messages/data structures are defined with protocol buffer definition files, which are available on GitHub. Using these files, you can generate Riva Speech AI services bindings to any supported language of your choice. The generated code can be compiled into your application, with the only additional dependency being the gRPC library.

Download the Riva API#

The process for generating bindings is dependent on the target language you intend to use for developing with Riva. The high-level steps, however, are the same.

  1. Download, build (if necessary), and install gRPC for your target platform and language.

  2. Obtain the gRPC service and protocol buffer definitions for Riva from GitHub or NGC:

    nvidia-riva/common

    git clone https://github.com/nvidia-riva/common.git
    cd common/riva/proto
    
  3. Generate the language-specific bindings using the protoc tool (refer to the gRPC docs).

  4. Write a client in your desired language with the generated bindings in the previous step.

Generate Language Bindings#

In this tutorial, we will build a Question Answering application with Riva written in Golang.

  1. Download and install the Golang compiler if you have not already. Ensure that $GOPATH/bin is in your environment $PATH so that you can use Golang-installed tools (like protoc).

  2. Install the Protocol Buffers and gRPC libraries for Golang.

    export GO111MODULE=on
    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    
  3. Create a directory for your project. Initialize a module with go mod.

    mkdir riva-qa-golang-client
    cd riva-qa-golang-client
    go mod init riva-qa
    
  4. Download and copy the Riva API definition from GitHub or NGC.

    wget -O riva-common.zip https://github.com/nvidia-riva/common/archive/main.zip
    unzip -j -d riva_speech riva-common.zip '*.proto'
    rm riva-common.zip
    
  5. Generate Golang bindings for the Riva NLP service.

    protoc --go_out=. --go_opt=paths=source_relative \
       --go-grpc_out=. --go-grpc_opt=paths=source_relative \
       riva_speech/riva_nlp.proto
    

Write the Client#

  1. Write a simple synchronous client. Using the text editor or IDE of your choice, create a source file for our executable qa.go with the following code.

    package main
    
    import (
        "context"
        "flag"
        "log"
        "time"
    
        "google.golang.org/grpc"
        pb "riva-qa/riva_speech"
    )
    
    func main() {
        serverFlag := flag.String("server", "localhost:50051", "Riva server to connect to")
        queryFlag := flag.String("query", "", "Question to ask")
        contextFlag := flag.String("context", "", "Context to search for answer")
    
        flag.Parse()
    
        if *queryFlag == "" || *contextFlag == "" {
            log.Fatal("-query and -context must both be set.")
        }
    
        // Set up a connection to the server.
        conn, err := grpc.Dial(*serverFlag, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(time.Second))
        if err != nil {
            log.Fatalf("Unable to connect to server: %v", err)
        }
        defer conn.Close()
        c := pb.NewRivaLanguageUnderstandingClient(conn)
    
        // Contact the server and print out its response.
        ctx, cancel := context.WithTimeout(context.Background(), time.Second)
        defer cancel()
    
        r, err := c.NaturalQuery(ctx, &pb.NaturalQueryRequest{
            Query:   *queryFlag,
            Context: *contextFlag,
            TopN:    1,
        })
    
        if err != nil {
            log.Fatalf("Issue encountered with Riva Request: %v", err)
        }
    
        log.Printf("Question: %s", *queryFlag)
        log.Printf("Answer:   %s", r.GetResults()[0].GetAnswer())
    }
    
  2. Compile and run the new client.

    go mod tidy
    go build qa.go
    ./qa -server <riva_uri> \
         -query "Which founder of NVIDIA previously worked at Sun?" \
         -context "Nvidia was founded on April 5, 1993, by Jensen Huang (CEO as of
                   2020), a Taiwanese American, previously director of CoreWare at LSI
                   Logic and a microprocessor designer at Advanced Micro Devices (AMD),
                   Chris Malachowsky, an electrical engineer who worked at Sun
                   Microsystems, and Curtis Priem, previously a senior staff engineer
                   and graphics chip designer at Sun Microsystems."
    
    2021/02/04 13:17:51 Question: Which founder of NVIDIA previously worked at Sun?
    2021/02/04 13:17:51 Answer:   Chris Malachowsky,