Basics tutorial

A basic tutorial introduction to gRPC in Python.

This tutorial provides a basic Python programmer’s introduction to working with gRPC.

By walking through this example you’ll learn how to:

  • Define a service in a .proto file.
  • Generate server and client code using the protocol buffer compiler.
  • Use the Python gRPC API to write a simple client and server for your service.

It assumes that you have read the Introduction to gRPC and are familiar with protocol buffers . You can find out more in the proto3 language guide and Python generated code guide .

Why use gRPC?

Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients.

With gRPC we can define our service once in a .proto file and generate clients and servers in any of gRPC’s supported languages, which in turn can be run in environments ranging from servers inside a large data center to your own tablet — all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating.

Example code and setup

The example code for this tutorial is in grpc/grpc/examples/python/route_guide . To download the example, clone the grpc repository by running the following command:

Then change your current directory to examples/python/route_guide in the repository:

You also should have the relevant tools installed to generate the server and client interface code - if you don’t already, follow the setup instructions in Quick start .

Defining the service

Your first step (as you’ll know from the Introduction to gRPC ) is to define the gRPC service and the method request and response types using protocol buffers . You can see the complete .proto file in examples/protos/route_guide.proto .

To define a service, you specify a named service in your .proto file:

Then you define rpc methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the RouteGuide service:

A simple RPC where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call.

A response-streaming RPC where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in the example, you specify a response-streaming method by placing the stream keyword before the response type.

A request-streaming RPC where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a request-streaming method by placing the stream keyword before the request type.

A bidirectionally-streaming RPC where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the stream keyword before both the request and the response.

Your .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here’s the Point message type:

Generating client and server code

Next you need to generate the gRPC client and server interfaces from your .proto service definition.

First, install the grpcio-tools package:

Use the following command to generate the Python code:

Note that as we’ve already provided a version of the generated code in the example directory, running this command regenerates the appropriate file rather than creates a new one. The generated code files are called route_guide_pb2.py and route_guide_pb2_grpc.py and contain:

  • classes for the messages defined in route_guide.proto
  • RouteGuideStub , which can be used by clients to invoke RouteGuide RPCs
  • RouteGuideServicer , which defines the interface for implementations of the RouteGuide service
  • add_RouteGuideServicer_to_server , which adds a RouteGuideServicer to a grpc.Server

Generating gRPC interfaces with custom package path

To generate gRPC client interfaces with a custom package path, you can use the -I parameter along with the grpc_tools.protoc command. This approach allows you to specify a custom package name for the generated files.

Here’s an example command to generate the gRPC client interfaces with a custom package path:

The generated files will be placed in the ./grpc/example/custom/path/ directory:

  • ./grpc/example/custom/path/route_guide_pb2.py
  • ./grpc/example/custom/path/route_guide_pb2_grpc.py

With this setup, the generated route_guide_pb2_grpc.py file will correctly import the protobuf definitions using the custom package structure, as shown below:

By following this approach, you can ensure that the files will call each other correctly with respect to the specified package path. This method allows you to maintain a custom package structure for your gRPC client interfaces.

Creating the server

First let’s look at how you create a RouteGuide server. If you’re only interested in creating gRPC clients, you can skip this section and go straight to Creating the client (though you might find it interesting anyway!).

Creating and running a RouteGuide server breaks down into two work items:

  • Implementing the servicer interface generated from our service definition with functions that perform the actual “work” of the service.
  • Running a gRPC server to listen for requests from clients and transmit responses.

You can find the example RouteGuide server in examples/python/route_guide/route_guide_server.py .

Implementing RouteGuide

route_guide_server.py has a RouteGuideServicer class that subclasses the generated class route_guide_pb2_grpc.RouteGuideServicer :

RouteGuideServicer implements all the RouteGuide service methods.

Let’s look at the simplest type first, GetFeature , which just gets a Point from the client and returns the corresponding feature information from its database in a Feature .

The method is passed a route_guide_pb2.Point request for the RPC, and a grpc.ServicerContext object that provides RPC-specific information such as timeout limits. It returns a route_guide_pb2.Feature response.

Response-streaming RPC

Now let’s look at the next method. ListFeatures is a response-streaming RPC that sends multiple Feature s to the client.

Here the request message is a route_guide_pb2.Rectangle within which the client wants to find Feature s. Instead of returning a single response the method yields zero or more responses.

Request-streaming RPC

The request-streaming method RecordRoute uses an iterator of request values and returns a single response value.

Bidirectional streaming RPC

Lastly let’s look at the bidirectionally-streaming method RouteChat .

This method’s semantics are a combination of those of the request-streaming method and the response-streaming method. It is passed an iterator of request values and is itself an iterator of response values.

Starting the server

Once you have implemented all the RouteGuide methods, the next step is to start up a gRPC server so that clients can actually use your service:

The server start() method is non-blocking. A new thread will be instantiated to handle requests. The thread calling server.start() will often not have any other work to do in the meantime. In this case, you can call server.wait_for_termination() to cleanly block the calling thread until the server terminates.

Creating the client

You can see the complete example client code in examples/python/route_guide/route_guide_client.py .

Creating a stub

To call service methods, we first need to create a stub .

We instantiate the RouteGuideStub class of the route_guide_pb2_grpc module, generated from our .proto .

Calling service methods

For RPC methods that return a single response (“response-unary” methods), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For response-streaming RPC methods, calls immediately return an iterator of response values. Calls to that iterator’s next() method block until the response to be yielded from the iterator becomes available.

A synchronous call to the simple RPC GetFeature is nearly as straightforward as calling a local method. The RPC call waits for the server to respond, and will either return a response or raise an exception:

An asynchronous call to GetFeature is similar, but like calling a local method asynchronously in a thread pool:

Calling the response-streaming ListFeatures is similar to working with sequence types:

Calling the request-streaming RecordRoute is similar to passing an iterator to a local method. Like the simple RPC above that also returns a single response, it can be called synchronously or asynchronously:

Calling the bidirectionally-streaming RouteChat has (as is the case on the service-side) a combination of the request-streaming and response-streaming semantics:

Try it out!

Run the server:

From a different terminal, run the client:

Python Generated Code Guide

Any differences between proto2 and proto3 generated code are highlighted - note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in both versions. You should read the proto2 language guide and/or proto3 language guide before reading this document.

The Python Protocol Buffers implementation is a little different from C++ and Java. In Python, the compiler only outputs code to build descriptors for the generated classes, and a Python metaclass does the real work. This document describes what you get after the metaclass has been applied.

Compiler Invocation

The protocol buffer compiler produces Python output when invoked with the --python_out= command-line flag. The parameter to the --python_out= option is the directory where you want the compiler to write your Python output. The compiler creates a .py file for each .proto file input. The names of the output files are computed by taking the name of the .proto file and making two changes:

  • The extension ( .proto ) is replaced with _pb2.py .
  • The proto path (specified with the --proto_path= or -I command-line flag) is replaced with the output path (specified with the --python_out= flag).

So, for example, let’s say you invoke the compiler as follows:

The compiler will read the files src/foo.proto and src/bar/baz.proto and produce two output files: build/gen/foo_pb2.py and build/gen/bar/baz_pb2.py . The compiler will automatically create the directory build/gen/bar if necessary, but it will not create build or build/gen ; they must already exist.

Protoc can generate Python stubs ( .pyi ) using the --pyi_out parameter.

Note that if the .proto file or its path contains any characters which cannot be used in Python module names (for example, hyphens), they will be replaced with underscores. So, the file foo-bar.proto becomes the Python file foo_bar_pb2.py .

The Python code generated by the protocol buffer compiler is completely unaffected by the package name defined in the .proto file. Instead, Python packages are identified by directory structure.

Given a simple message declaration:

The protocol buffer compiler generates a class called Foo , which subclasses google.protobuf.Message . The class is a concrete class; no abstract methods are left unimplemented. Unlike C++ and Java, Python generated code is unaffected by the optimize_for option in the .proto file; in effect, all Python code is optimized for code size.

If the message’s name is a Python keyword, then its class will only be accessible via getattr() , as described in the Names which conflict with Python keywords section.

You should not create your own Foo subclasses. Generated classes are not designed for subclassing and may lead to "fragile base class" problems. Besides, implementation inheritance is bad design.

Python message classes have no particular public members other than those defined by the Message interface and those generated for nested fields, messages, and enum types (described below). Message provides methods you can use to check, manipulate, read, or write the entire message, including parsing from and serializing to binary strings. In addition to these methods, the Foo class defines the following static methods:

  • FromString(s) : Returns a new message instance deserialized from the given string.

Note that you can also use the text_format module to work with protocol messages in text format: for example, the Merge() method lets you merge an ASCII representation of a message into an existing message.

Nested Types

A message can be declared inside another message. For example:

In this case, the Bar class is declared as a static member of Foo , so you can refer to it as Foo.Bar .

Well Known Types

Protocol buffers provides a number of well-known types that you can use in your .proto files along with your own message types. Some WKT messages have special methods in addition to the usual protocol buffer message methods, as they subclass both google.protobuf.Message and a WKT class.

For Any messages, you can call Pack() to pack a specified message into the current Any message, or Unpack() to unpack the current Any message into a specified message. For example:

Unpack() also checks the descriptor of the passed-in message object against the stored one and returns False if they don’t match and does not attempt any unpacking; True otherwise.

You can also call the Is() method to check if the Any message represents the given protocol buffer type. For example:

Use the TypeName() method to retrieve the protobuf type name of an inner message.

Timestamp messages can be converted to/from RFC 3339 date string format (JSON string) using the ToJsonString() / FromJsonString() methods. For example:

You can also call GetCurrentTime() to fill the Timestamp message with current time:

To convert between other time units since epoch, you can call ToNanoseconds(), FromNanoseconds(), ToMicroseconds(), FromMicroseconds(), ToMilliseconds(), FromMilliseconds(), ToSeconds() , or FromSeconds() . The generated code also has ToDatetime() and FromDatetime() methods to convert between Python datetime objects and Timestamps. For example:

Duration messages have the same methods as Timestamp to convert between JSON string and other time units. To convert between timedelta and Duration, you can call ToTimedelta() or FromTimedelta . For example:

FieldMask messages can be converted to/from JSON string using the ToJsonString() / FromJsonString() methods. In addition, a FieldMask message has the following methods:

  • IsValidForDescriptor(message_descriptor) : Checks whether the FieldMask is valid for Message Descriptor.
  • AllFieldsFromDescriptor(message_descriptor) : Gets all direct fields of Message Descriptor to FieldMask.
  • CanonicalFormFromMask(mask) : Converts a FieldMask to the canonical form.
  • Union(mask1, mask2) : Merges two FieldMasks into this FieldMask.
  • Intersect(mask1, mask2) : Intersects two FieldMasks into this FieldMask.
  • MergeMessage(source, destination, replace_message_field=False, replace_repeated_field=False) : Merges fields specified in FieldMask from source to destination.

Struct messages let you get and set the items directly. For example:

To get or create a list/struct, you can call get_or_create_list() / get_or_create_struct() . For example:

A ListValue message acts like a Python sequence that lets you do the following:

To add a ListValue/Struct, call add_list() / add_struct() . For example:

For each field in a message type, the corresponding class has a property with the same name as the field. How you can manipulate the property depends on its type.

As well as a property, the compiler generates an integer constant for each field containing its field number. The constant name is the field name converted to upper-case followed by _FIELD_NUMBER . For example, given the field optional int32 foo_bar = 5; , the compiler will generate the constant FOO_BAR_FIELD_NUMBER = 5 .

If the field’s name is a Python keyword, then its property will only be accessible via getattr() and setattr() , as described in the Names which conflict with Python keywords section.

Singular Fields (proto2)

If you have a singular (optional or required) field foo of any non-message type, you can manipulate the field foo as if it were a regular field. For example, if foo ’s type is int32 , you can say:

Note that setting foo to a value of the wrong type will raise a TypeError .

If foo is read when it is not set, its value is the default value for that field. To check if foo is set, or to clear the value of foo , you must call the HasField() or ClearField() methods of the Message interface. For example:

Singular Fields (proto3)

If you have a singular field foo of any non-message type, you can manipulate the field foo as if it were a regular field. For example, if foo ’s type is int32 , you can say:

If foo is read when it is not set, its value is the default value for that field. To clear the value of foo and reset it to the default value for its type, you call the ClearField() method of the Message interface. For example:

Singular Message Fields

Message types work slightly differently. You cannot assign a value to an embedded message field. Instead, assigning a value to any field within the child message implies setting the message field in the parent. You can also use the parent message’s HasField() method to check if a message type field value has been set.

So, for example, let’s say you have the following .proto definition:

You cannot do the following:

Instead, to set bar , you simply assign a value directly to a field within bar , and - presto! - foo has a bar field:

Similarly, you can set bar using the Message interface’s CopyFrom() method. This copies all the values from another message of the same type as bar .

Note that simply reading a field inside bar does not set the field:

If you need the "has" bit on a message that does not have any fields you can or want to set, you may use the SetInParent() method.

Repeated Fields

Repeated fields are represented as an object that acts like a Python sequence. As with embedded messages, you cannot assign the field directly, but you can manipulate it. For example, given this message definition:

You can do the following:

The ClearField() method of the Message interface works in addition to using Python del .

When using the index to retrieve a value, you can use negative numbers, such as using -1 to retrieve the last element in the list. If your index goes out of bounds, you’ll get an IndexError: list index out of range .

Repeated Message Fields

Repeated message fields work similar to repeated scalar fields. However, the corresponding Python object also has an add() method that creates a new message object, appends it to the list, and returns it for the caller to fill in. Also, the object’s append() method makes a copy of the given message and appends that copy to the list. This is done so that messages are always owned by the parent message to avoid circular references and other confusion that can happen when a mutable data structure has multiple owners. Similarly, the object’s extend() method appends an entire list of messages, but makes a copy of every message in the list.

For example, given this message definition:

Unlike repeated scalar fields, repeated message fields don’t support item assignment (i.e. __setitem__ ). For example:

Groups (proto2)

Note that groups are deprecated and should not be used when creating new message types – use nested message types instead.

A group combines a nested message type and a field into a single declaration, and uses a different wire format for the message. The generated message has the same name as the group. The generated field’s name is the lowercased name of the group.

For example, except for wire format, the following two message definitions are equivalent:

A group is either required , optional , or repeated . A required or optional group is manipulated using the same API as a regular singular message field. A repeated group is manipulated using the same API as a regular repeated message field.

For example, given the above SearchResponse definition, you can do the following:

Given this message definition:

The generated Python API for the map field is just like a Python dict :

As with embedded message fields , messages cannot be directly assigned into a map value. Instead, to add a message as a map value you reference an undefined key , which constructs and returns a new submessage:

You can find out more about undefined keys in the next section.

Referencing undefined keys

The semantics of Protocol Buffer maps behave slightly differently to Python dict s when it comes to undefined keys. In a regular Python dict , referencing an undefined key raises a KeyError exception:

However, in Protocol Buffers maps, referencing an undefined key creates the key in the map with a zero/false/empty value. This behavior is more like the Python standard library defaultdict .

This behavior is especially convenient for maps with message type values, because you can directly update the fields of the returned message.

Note that even if you don’t assign any values to message fields, the submessage is still created in the map:

This is different from regular embedded message fields , where the message itself is only created once you assign a value to one of its fields.

As it may not be immediately obvious to anyone reading your code that m.message_map[10] alone, for example, may create a submessage, we also provide a get_or_create() method that does the same thing but whose name makes the possible message creation more explicit:

Enumerations

In Python, enums are just integers. A set of integral constants are defined corresponding to the enum’s defined values. For example, given:

The constants VALUE_A , VALUE_B , and VALUE_C are defined with values 0, 5, and 1234, respectively. You can access SomeEnum if desired. If an enum is defined in the outer scope, the values are module constants; if it is defined within a message (like above), they become static members of that message class.

For example, you can access the values in the three following ways for the following enum in a proto:

An enum field works just like a scalar field.

If the enum’s name (or an enum value) is a Python keyword, then its object (or the enum value’s property) will only be accessible via getattr() , as described in the Names which conflict with Python keywords section.

The values you can set in an enum depend on your protocol buffers version:

  • In proto2 , an enum cannot contain a numeric value other than those defined for the enum type. If you assign a value that is not in the enum, the generated code will throw an exception.
  • proto3 uses open enum semantics: enum fields can contain any int32 value.

Enums have a number of utility methods for getting field names from values and vice versa, lists of fields, and so on - these are defined in enum_type_wrapper.EnumTypeWrapper (the base class for generated enum classes). So, for example, if you have the following standalone enum in myproto.proto :

…you can do this:

For an enum declared within a protocol message, such as Foo above, the syntax is similar:

If multiple enum constants have the same value (aliases), the first constant defined is returned.

In the above example, myproto_pb2.SomeEnum.Name(5) returns "VALUE_B" .

Given a message with a oneof:

The Python class corresponding to Foo will have properties called name and serial_number just like regular fields . However, unlike regular fields, at most one of the fields in a oneof can be set at a time, which is ensured by the runtime. For example:

The message class also has a WhichOneof method that lets you find out which field (if any) in the oneof has been set. This method returns the name of the field that is set, or None if nothing has been set:

HasField and ClearField also accept oneof names in addition to field names:

Note that calling ClearField on a oneof just clears the currently set field.

Names which conflict with Python keywords

If the name of a message, field, enum, or enum value is a Python keyword , then the name of its corresponding class or property will be the same, but you’ll only be able to access it using Python’s getattr() and setattr() built-in functions, and not via Python’s normal attribute reference syntax (i.e. the dot operator).

For example, if you have the following .proto definition:

You would access those fields like this:

By contrast, trying to use obj.attr syntax to access these fields results in Python raising syntax errors when parsing your code:

Extensions (proto2 only)

Given a message with an extension range:

The Python class corresponding to Foo will have a member called Extensions , which is a dictionary mapping extension identifiers to their current values.

Given an extension definition:

The protocol buffer compiler generates an "extension identifier" called bar . The identifier acts as a key to the Extensions dictionary. The result of looking up a value in this dictionary is exactly the same as if you accessed a normal field of the same type. So, given the above example, you could do:

Note that you need to specify the extension identifier constant, not just a string name: this is because it’s possible for multiple extensions with the same name to be specified in different scopes.

Analogous to normal fields, Extensions[...] returns a message object for singular messages and a sequence for repeated fields.

The Message interface’s HasField() and ClearField() methods do not work with extensions; you must use HasExtension() and ClearExtension() instead. To use the HasExtension() and ClearExtension() methods, pass in the field_descriptor for the extension you are checking for the existence of.

If the .proto file contains the following line:

Then the protocol buffer compiler will generate code based on the service definitions found in the file as described in this section. However, the generated code may be undesirable as it is not tied to any particular RPC system, and thus requires more levels of indirection that code tailored to one system. If you do NOT want this code to be generated, add this line to the file:

If neither of the above lines are given, the option defaults to false , as generic services are deprecated. (Note that prior to 2.4.0, the option defaults to true )

RPC systems based on .proto -language service definitions should provide plugins to generate code appropriate for the system. These plugins are likely to require that abstract services are disabled, so that they can generate their own classes of the same names. Plugins are new in version 2.3.0 (January 2010).

The remainder of this section describes what the protocol buffer compiler generates when abstract services are enabled.

Given a service definition:

The protocol buffer compiler will generate a class Foo to represent this service. Foo will have a method for each method defined in the service definition. In this case, the method Bar is defined as:

The parameters are equivalent to the parameters of Service.CallMethod() , except that the method_descriptor argument is implied.

These generated methods are intended to be overridden by subclasses. The default implementations simply call controller.SetFailed() with an error message indicating that the method is unimplemented, then invoke the done callback. When implementing your own service, you must subclass this generated service and implement its methods as appropriate.

Foo subclasses the Service interface. The protocol buffer compiler automatically generates implementations of the methods of Service as follows:

  • GetDescriptor : Returns the service’s ServiceDescriptor .
  • CallMethod : Determines which method is being called based on the provided method descriptor and calls it directly.
  • GetRequestClass and GetResponseClass : Returns the class of the request or response of the correct type for the given method.

The protocol buffer compiler also generates a "stub" implementation of every service interface, which is used by clients wishing to send requests to servers implementing the service. For the Foo service (above), the stub implementation Foo_Stub will be defined.

Foo_Stub is a subclass of Foo . Its constructor takes an RpcChannel as a parameter. The stub then implements each of the service’s methods by calling the channel’s CallMethod() method.

The Protocol Buffer library does not include an RPC implementation. However, it includes all of the tools you need to hook up a generated service class to any arbitrary RPC implementation of your choice. You need only provide implementations of RpcChannel and RpcController .

Plugin Insertion Points

Code generator plugins which want to extend the output of the Python code generator may insert code of the following types using the given insertion point names.

  • imports : Import statements.
  • module_scope : Top-level declarations.

Sharing Messages Between Python and C++

Prior to the 4.21.0 version of the Protobuf Python API, Python apps could share messages with C++ using a native extension. Starting in the 4.21.0 API version, sharing messages between Python and C++ is not supported by the default install. To enable this capability when working with the 4.x and later versions of the Protobuf Python API, define the environment variable, PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp , and ensure that the Python/C++ extension is installed.

  • Further Reading

A Beginner's Guide to gRPC with Python ¶

Introduction to grpc ¶.

Have you heard of gRPC, high-performance, open-source framework that allows developers to build distributed systems and microservices ?

gPRC uses protocol buffers as its interface definition language and provides features such as bi-directional streaming and flow control.

In this blog post, we will explore how to get started with gRPC in Python using the official gRPC Python library. We will walk through a simple working example that demonstrates how to:

  • Define a service in a .proto file
  • Generate server and client code using the protocol buffer compiler
  • Use the Python gRPC API to write a simple client and server for your service

Advantages of gRPC ¶

gRPC offers several advantages, making it a versatile and efficient choice for building distributed systems and microservices:

  • Language Independence : gRPC supports multiple languages seamlessly, allowing developers to build distributed systems using their preferred programming language.
  • Open Source & Multilingual Support : Being open source, gRPC enjoys support across various programming languages, making it a widely adopted solution for building distributed systems.
  • Boilerplate Elimination : gRPC generates code, reducing the need for boilerplate code and simplifying the development process.
  • Efficient Data Encoding : gRPC utilizes buffers instead of JSON for data encoding, resulting in lighter data transmission.

Getting Started with gRPC in Python ¶

Quick setup ¶.

Follow the steps below to set up a Python environment for gRPC 1 :

  • Quick Setup:
  • Install gRPC and gRPC Tools:
  • protoc , the buffer compiler
  • A plugin to generate client and server-side code from .proto files.

Testing an Example ¶

Clone the gRPC repository to access a sample project:

Run the server in one terminal:

Run the client in another:

Congratulations! You've run your first gRPC application!

What the code does ¶

The provided code includes a Protocol Buffers (protobuf) definition, a server-side implementation in Python, and a client-side implementation in Python. The protobuf definition defines a Greeter service with three RPC methods: SayHello , and SayHelloStreamReply . The server-side implementation defines the behavior of the SayHello method, while the client-side implementation makes use of these methods to communicate with the server.

The helloworld.proto file defines the Greeter service with three RPC methods. The greeter_server.py file implements the server for the Greeter service, and the greeter_client.py file implements the client to communicate with the server. The python -m grpc_tools.protoc command is used to compile the .proto file and generate the necessary Python code for the server and client.

Adding an Extra Method on the Server ¶

  • Modify ../../protos/helloworld.proto ( grpc/examples/protos/helloworld.proto ) and the files greeter_server.py and greeter_client.py in the examples/python/helloworld folder.
  • Compile the .proto file and generate the necessary Python code for the server and client
  • Run the client and server again:

What just happened ¶

Well, we have added another RPC method, called here SayHelloAgain . The implementation includes:

  • The protobuf definition in the Greeter service in the greeter_server.py
  • The server-side implementation in greeter_server.py

So, when running the server then the client, we should receive two responses

The server output should remain the same

But the client will receive two responses from the server.

The python -m grpc_tools.protoc command is used to compile the .proto file and generate the necessary Python code for the server and client. This command takes the following arguments:

  • -I../../protos : Specifies the directory containing the .proto file.
  • --python_out=. : Specifies the output directory for the generated Python code.
  • --grpc_python_out=. : Specifies the output directory for the generated gRPC Python code.

This command generates the helloworld_pb2.py file, which contains the generated request and response classes, and the helloworld_pb2_grpc.py file, which contains the generated server and client stubs.

The python -m grpc_tools.protoc command is the recommended way to generate Python code from a .proto file for use with gRPC.

For more information, you can refer to the gRPC Python documentation and the Protocol Buffer Basics: Python tutorial.

If you need to compile .proto files for other programming languages, the process may differ, and you can refer to the respective language's gRPC documentation for guidance.

Further Reading ¶

  • Introduction to gRPC
  • gRPC Core Concepts
  • Explore the Python API Reference to discover functions and classes.

For more detailed instructions, refer to the gRPC Python Quickstart 1 .

https://grpc.io/docs/languages/python/quickstart/   ↩ ↩

gRPC Python

  • insecure_channel()
  • secure_channel()
  • intercept_channel()
  • ssl_channel_credentials()
  • metadata_call_credentials()
  • access_token_call_credentials()
  • composite_call_credentials()
  • composite_channel_credentials()
  • local_channel_credentials()
  • compute_engine_channel_credentials()
  • ssl_server_credentials()
  • ssl_server_certificate_configuration()
  • dynamic_ssl_server_credentials()
  • local_server_credentials()
  • LocalConnectionType.UDS
  • LocalConnectionType.LOCAL_TCP
  • unary_unary_rpc_method_handler()
  • unary_stream_rpc_method_handler()
  • stream_unary_rpc_method_handler()
  • stream_stream_rpc_method_handler()
  • method_handlers_generic_handler()
  • channel_ready_future()
  • ChannelConnectivity.IDLE
  • ChannelConnectivity.CONNECTING
  • ChannelConnectivity.READY
  • ChannelConnectivity.TRANSIENT_FAILURE
  • ChannelConnectivity.SHUTDOWN
  • StatusCode.OK
  • StatusCode.CANCELLED
  • StatusCode.UNKNOWN
  • StatusCode.INVALID_ARGUMENT
  • StatusCode.DEADLINE_EXCEEDED
  • StatusCode.NOT_FOUND
  • StatusCode.ALREADY_EXISTS
  • StatusCode.PERMISSION_DENIED
  • StatusCode.UNAUTHENTICATED
  • StatusCode.RESOURCE_EXHAUSTED
  • StatusCode.FAILED_PRECONDITION
  • StatusCode.ABORTED
  • StatusCode.UNIMPLEMENTED
  • StatusCode.INTERNAL
  • StatusCode.UNAVAILABLE
  • StatusCode.DATA_LOSS
  • Channel.__enter__()
  • Channel.__exit__()
  • Channel.close()
  • Channel.stream_stream()
  • Channel.stream_unary()
  • Channel.subscribe()
  • Channel.unary_stream()
  • Channel.unary_unary()
  • Channel.unsubscribe()
  • Server.add_generic_rpc_handlers()
  • Server.add_insecure_port()
  • Server.add_secure_port()
  • Server.start()
  • Server.stop()
  • Server.wait_for_termination()
  • ChannelCredentials
  • CallCredentials
  • AuthMetadataContext.service_url
  • AuthMetadataContext.method_name
  • AuthMetadataPluginCallback.__call__()
  • AuthMetadataPlugin.__call__()
  • ServerCredentials
  • ServerCertificateConfiguration
  • RpcContext.add_callback()
  • RpcContext.cancel()
  • RpcContext.is_active()
  • RpcContext.time_remaining()
  • Call.code()
  • Call.details()
  • Call.initial_metadata()
  • Call.trailing_metadata()
  • ClientCallDetails.method
  • ClientCallDetails.timeout
  • ClientCallDetails.metadata
  • ClientCallDetails.credentials
  • ClientCallDetails.wait_for_ready
  • ClientCallDetails.compression
  • UnaryUnaryClientInterceptor.intercept_unary_unary()
  • UnaryStreamClientInterceptor.intercept_unary_stream()
  • StreamUnaryClientInterceptor.intercept_stream_unary()
  • StreamStreamClientInterceptor.intercept_stream_stream()
  • ServicerContext.abort()
  • ServicerContext.abort_with_status()
  • ServicerContext.auth_context()
  • ServicerContext.code()
  • ServicerContext.details()
  • ServicerContext.disable_next_message_compression()
  • ServicerContext.invocation_metadata()
  • ServicerContext.peer()
  • ServicerContext.peer_identities()
  • ServicerContext.peer_identity_key()
  • ServicerContext.send_initial_metadata()
  • ServicerContext.set_code()
  • ServicerContext.set_compression()
  • ServicerContext.set_details()
  • ServicerContext.set_trailing_metadata()
  • ServicerContext.trailing_metadata()
  • RpcMethodHandler.request_streaming
  • RpcMethodHandler.response_streaming
  • RpcMethodHandler.request_deserializer
  • RpcMethodHandler.response_serializer
  • RpcMethodHandler.unary_unary
  • RpcMethodHandler.unary_stream
  • RpcMethodHandler.stream_unary
  • RpcMethodHandler.stream_stream
  • HandlerCallDetails.method
  • HandlerCallDetails.invocation_metadata
  • GenericRpcHandler.service()
  • ServiceRpcHandler.service_name()
  • ServerInterceptor.intercept_service()
  • UnaryUnaryMultiCallable.__call__()
  • UnaryUnaryMultiCallable.future()
  • UnaryUnaryMultiCallable.with_call()
  • UnaryStreamMultiCallable.__call__()
  • StreamUnaryMultiCallable.__call__()
  • StreamUnaryMultiCallable.future()
  • StreamUnaryMultiCallable.with_call()
  • StreamStreamMultiCallable.__call__()
  • FutureTimeoutError
  • FutureCancelledError
  • Future.add_done_callback()
  • Future.cancel()
  • Future.cancelled()
  • Future.done()
  • Future.exception()
  • Future.result()
  • Future.running()
  • Future.traceback()
  • Compression.NoCompression
  • Compression.Deflate
  • Compression.Gzip
  • protos_and_services()
  • gRPC AsyncIO API
  • gRPC Channelz
  • gRPC Health Checking
  • gRPC Reflection
  • gRPC Status
  • gRPC Testing
  • gRPC Python Observability

Related Topics

  • Previous: Welcome to gRPC Python’s documentation!
  • Next: gRPC AsyncIO API

Quick search

For documentation, examples, and more, see the Python gRPC page on grpc.io .

Module Contents ¶

The version string is available as grpc.__version__ .

Create Client ¶

Creates an insecure Channel to a server.

The returned Channel is thread-safe.

target – The server address

options – An optional list of key-value pairs ( channel_arguments in gRPC Core runtime) to configure the channel.

compression – An optional value indicating the compression method to be used over the lifetime of the channel.

Creates a secure Channel to a server.

target – The server address.

credentials – A ChannelCredentials instance.

Intercepts a channel through a set of interceptors.

channel – A Channel.

interceptors – Zero or more objects of type UnaryUnaryClientInterceptor, UnaryStreamClientInterceptor, StreamUnaryClientInterceptor, or StreamStreamClientInterceptor. Interceptors are given control in the order they are listed.

A Channel that intercepts each invocation via the provided interceptors.

TypeError – If interceptor does not derive from any of UnaryUnaryClientInterceptor, UnaryStreamClientInterceptor, StreamUnaryClientInterceptor, or StreamStreamClientInterceptor.

Create Client Credentials ¶

Creates a ChannelCredentials for use with an SSL-enabled Channel.

root_certificates – The PEM-encoded root certificates as a byte string, or None to retrieve them from a default location chosen by gRPC runtime.

private_key – The PEM-encoded private key as a byte string, or None if no private key should be used.

certificate_chain – The PEM-encoded certificate chain as a byte string to use or None if no certificate chain should be used.

A ChannelCredentials for use with an SSL-enabled Channel.

Construct CallCredentials from an AuthMetadataPlugin.

metadata_plugin – An AuthMetadataPlugin to use for authentication.

name – An optional name for the plugin.

A CallCredentials.

Construct CallCredentials from an access token.

access_token – A string to place directly in the http request authorization header, for example “authorization: Bearer <access_token>”.

Compose multiple CallCredentials to make a new CallCredentials.

*call_credentials – At least two CallCredentials objects.

A CallCredentials object composed of the given CallCredentials objects.

Compose a ChannelCredentials and one or more CallCredentials objects.

channel_credentials – A ChannelCredentials object.

*call_credentials – One or more CallCredentials objects.

CallCredentials objects.

Creates a local ChannelCredentials used for local connections.

This is an EXPERIMENTAL API.

Local credentials are used by local TCP endpoints (e.g. localhost:10000) also UDS connections.

The connections created by local channel credentials are not encrypted, but will be checked if they are local or not. The UDS connections are considered secure by providing peer authentication and data confidentiality while TCP connections are considered insecure.

It is allowed to transmit call credentials over connections created by local channel credentials.

Local channel credentials are useful for 1) eliminating insecure_channel usage; 2) enable unit testing for call credentials without setting up secrets.

local_connect_type – Local connection type (either grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP)

A ChannelCredentials for use with a local Channel

Creates a compute engine channel credential.

This credential can only be used in a GCP environment as it relies on a handshaker service. For more info about ALTS, see https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security

This channel credential is expected to be used as part of a composite credential in conjunction with a call credentials that authenticates the VM’s default service account. If used with any other sort of call credential, the connection may suddenly and unexpectedly begin failing RPCs.

Create Server ¶

Creates a Server with which RPCs can be serviced.

thread_pool – A futures.ThreadPoolExecutor to be used by the Server to execute RPC handlers.

handlers – An optional list of GenericRpcHandlers used for executing RPCs. More handlers may be added by calling add_generic_rpc_handlers any time before the server is started.

interceptors – An optional list of ServerInterceptor objects that observe and optionally manipulate the incoming RPCs before handing them over to handlers. The interceptors are given control in the order they are specified. This is an EXPERIMENTAL API.

options – An optional list of key-value pairs ( channel_arguments in gRPC runtime) to configure the channel.

maximum_concurrent_rpcs – The maximum number of concurrent RPCs this server will service before returning RESOURCE_EXHAUSTED status, or None to indicate no limit.

compression – An element of grpc.compression, e.g. grpc.compression.Gzip. This compression algorithm will be used for the lifetime of the server unless overridden.

xds – If set to true, retrieves server configuration via xDS. This is an EXPERIMENTAL option.

A Server object.

Create Server Credentials ¶

Creates a ServerCredentials for use with an SSL-enabled Server.

private_key_certificate_chain_pairs – A list of pairs of the form [PEM-encoded private key, PEM-encoded certificate chain].

root_certificates – An optional byte string of PEM-encoded client root certificates that the server will use to verify client authentication. If omitted, require_client_auth must also be False.

require_client_auth – A boolean indicating whether or not to require clients to be authenticated. May only be True if root_certificates is not None.

A ServerCredentials for use with an SSL-enabled Server. Typically, this object is an argument to add_secure_port() method during server setup.

Creates a ServerCertificateConfiguration for use with a Server.

private_key_certificate_chain_pairs – A collection of pairs of the form [PEM-encoded private key, PEM-encoded certificate chain].

root_certificates – An optional byte string of PEM-encoded client root certificates that the server will use to verify client authentication.

configuration fetching callback.

initial_certificate_configuration ( ServerCertificateConfiguration ) – The certificate configuration with which the server will be initialized.

certificate_configuration_fetcher ( callable ) – A callable that takes no arguments and should return a ServerCertificateConfiguration to replace the server’s current certificate, or None for no change (i.e., the server will continue its current certificate config). The library will call this callback on every new client connection before starting the TLS handshake with the client, thus allowing the user application to optionally return a new ServerCertificateConfiguration that the server will then use for the handshake.

require_client_authentication – A boolean indicating whether or not to require clients to be authenticated.

A ServerCredentials.

Creates a local ServerCredentials used for local connections.

The connections created by local server credentials are not encrypted, but will be checked if they are local or not. The UDS connections are considered secure by providing peer authentication and data confidentiality while TCP connections are considered insecure.

It is allowed to transmit call credentials over connections created by local server credentials.

Local server credentials are useful for 1) eliminating insecure_channel usage; 2) enable unit testing for call credentials without setting up secrets.

A ServerCredentials for use with a local Server

Local Connection Type ¶

Types of local connection for local credential creation.

Unix domain socket connections

Local TCP connections.

RPC Method Handlers ¶

Creates an RpcMethodHandler for a unary-unary RPC method.

behavior – The implementation of an RPC that accepts one request and returns one response.

request_deserializer – An optional deserializer for request deserialization.

response_serializer – An optional serializer for response serialization.

An RpcMethodHandler object that is typically used by grpc.Server.

Creates an RpcMethodHandler for a unary-stream RPC method.

behavior – The implementation of an RPC that accepts one request and returns an iterator of response values.

Creates an RpcMethodHandler for a stream-unary RPC method.

behavior – The implementation of an RPC that accepts an iterator of request values and returns a single response value.

Creates an RpcMethodHandler for a stream-stream RPC method.

behavior – The implementation of an RPC that accepts an iterator of request values and returns an iterator of response values.

Creates a GenericRpcHandler from RpcMethodHandlers.

service – The name of the service that is implemented by the method_handlers.

method_handlers – A dictionary that maps method names to corresponding RpcMethodHandler.

A GenericRpcHandler. This is typically added to the grpc.Server object with add_generic_rpc_handlers() before starting the server.

Channel Ready Future ¶

Creates a Future that tracks when a Channel is ready.

Cancelling the Future does not affect the channel’s state machine. It merely decouples the Future from channel state machine.

channel – A Channel object.

A Future object that matures when the channel connectivity is ChannelConnectivity.READY.

Channel Connectivity ¶

Mirrors grpc_connectivity_state in the gRPC Core.

The channel is idle.

The channel is connecting.

The channel is ready to conduct RPCs.

The channel has seen a failure from which it expects to recover.

The channel has seen a failure from which it cannot recover.

gRPC Status Code ¶

Mirrors grpc_status_code in the gRPC Core.

Not an error; returned on success

The operation was cancelled (typically by the caller).

Unknown error.

Client specified an invalid argument.

Deadline expired before operation could complete.

Some requested entity (e.g., file or directory) was not found.

Some entity that we attempted to create (e.g., file or directory) already exists.

The caller does not have permission to execute the specified operation.

The request does not have valid authentication credentials for the operation.

Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.

Operation was rejected because the system is not in a state required for the operation’s execution.

The operation was aborted, typically due to a concurrency issue like sequencer check failures, transaction aborts, etc.

Operation is not implemented or not supported/enabled in this service.

Internal errors. Means some invariants expected by underlying system has been broken.

The service is currently unavailable.

Unrecoverable data loss or corruption.

Channel Object ¶

Affords RPC invocation via generic methods on client-side.

Channel objects implement the Context Manager type, although they need not support being entered and exited multiple times.

Enters the runtime context related to the channel object.

Exits the runtime context related to the channel object.

Closes this Channel and releases all resources held by it.

Closing the Channel will immediately terminate all RPCs active with the Channel and it is not valid to invoke new RPCs with the Channel.

This method is idempotent.

Creates a StreamStreamMultiCallable for a stream-stream method.

method – The name of the RPC method.

request_serializer – Optional serializer for serializing the request message. Request goes unserialized in case None is passed.

response_deserializer – Optional deserializer for deserializing the response message. Response goes undeserialized in case None is passed.

A StreamStreamMultiCallable value for the named stream-stream method.

Creates a StreamUnaryMultiCallable for a stream-unary method.

A StreamUnaryMultiCallable value for the named stream-unary method.

Subscribe to this Channel’s connectivity state machine.

A Channel may be in any of the states described by ChannelConnectivity. This method allows application to monitor the state transitions. The typical use case is to debug or gain better visibility into gRPC runtime’s state.

callback – A callable to be invoked with ChannelConnectivity argument. ChannelConnectivity describes current state of the channel. The callable will be invoked immediately upon subscription and again for every change to ChannelConnectivity until it is unsubscribed or this Channel object goes out of scope.

try_to_connect – A boolean indicating whether or not this Channel should attempt to connect immediately. If set to False, gRPC runtime decides when to connect.

Creates a UnaryStreamMultiCallable for a unary-stream method.

A UnaryStreamMultiCallable value for the name unary-stream method.

Creates a UnaryUnaryMultiCallable for a unary-unary method.

A UnaryUnaryMultiCallable value for the named unary-unary method.

Unsubscribes a subscribed callback from this Channel’s connectivity.

callback – A callable previously registered with this Channel from

method. ( having been passed to its "subscribe" ) –

Server Object ¶

Services RPCs.

Registers GenericRpcHandlers with this Server.

This method is only safe to call before the server is started.

generic_rpc_handlers – An iterable of GenericRpcHandlers that will be

RPCs. ( used to service ) –

Opens an insecure port for accepting RPCs.

This method may only be called before starting the server.

address – The address for which to open a port. If the port is 0, or not specified in the address, then gRPC runtime will choose a port.

An integer port on which server will accept RPC requests.

Opens a secure port for accepting RPCs.

address – The address for which to open a port. if the port is 0, or not specified in the address, then gRPC runtime will choose a port.

server_credentials – A ServerCredentials object.

Starts this Server.

This method may only be called once. (i.e. it is not idempotent).

Stops this Server.

This method immediately stop service of new RPCs in all cases.

If a grace period is specified, this method returns immediately and all RPCs active at the end of the grace period are aborted. If a grace period is not specified (by passing None for grace ), all existing RPCs are aborted immediately and this method blocks until the last RPC handler terminates.

This method is idempotent and may be called at any time. Passing a smaller grace value in a subsequent call will have the effect of stopping the Server sooner (passing None will have the effect of stopping the server immediately). Passing a larger grace value in a subsequent call will not have the effect of stopping the server later (i.e. the most restrictive grace value is used).

grace – A duration of time in seconds or None.

A threading.Event that will be set when this Server has completely stopped, i.e. when running RPCs either complete or are aborted and all handlers have terminated.

Block current thread until the server stops.

The wait will not consume computational resources during blocking, and it will block until one of the two following conditions are met:

The server is stopped or terminated;

A timeout occurs if timeout is not None .

The timeout argument works in the same way as threading.Event.wait() . https://docs.python.org/3/library/threading.html#threading.Event.wait

timeout – A floating point number specifying a timeout for the operation in seconds.

A bool indicates if the operation times out.

Authentication & Authorization Objects ¶

An encapsulation of the data required to create a secure Channel.

This class has no supported interface - it exists to define the type of its instances and its instances exist to be passed to other functions. For example, ssl_channel_credentials returns an instance of this class and secure_channel requires an instance of this class.

An encapsulation of the data required to assert an identity over a call.

A CallCredentials has to be used with secure Channel, otherwise the metadata will not be transmitted to the server.

A CallCredentials may be composed with ChannelCredentials to always assert identity for every call over that Channel.

This class has no supported interface - it exists to define the type of its instances and its instances exist to be passed to other functions.

Provides information to call credentials metadata plugins.

A string URL of the service being called into.

A string of the fully qualified method name being called.

Callback object received by a metadata plugin.

Passes to the gRPC runtime authentication metadata for an RPC.

metadata – The metadata used to construct the CallCredentials.

error – An Exception to indicate error or None to indicate success.

A specification for custom authentication.

Implements authentication by passing metadata to a callback.

This method will be invoked asynchronously in a separate thread.

context – An AuthMetadataContext providing information on the RPC that the plugin is being called to authenticate.

callback – An AuthMetadataPluginCallback to be invoked either synchronously or asynchronously.

An encapsulation of the data required to open a secure port on a Server.

A certificate configuration for use with an SSL-enabled Server.

Instances of this class can be returned in the certificate configuration fetching callback.

This class has no supported interface – it exists to define the type of its instances and its instances exist to be passed to other functions.

gRPC Exceptions ¶

Raised by the gRPC library to indicate non-OK-status RPC termination.

RPC Context ¶

Provides RPC-related information and action.

Registers a callback to be called on RPC termination.

callback – A no-parameter callable to be called on RPC termination.

the callback was not added and will not be called (because the RPC already terminated or some other reason).

Cancels the RPC.

Idempotent and has no effect if the RPC has already terminated.

Describes whether the RPC is active or has terminated.

True if RPC is active, False otherwise.

Describes the length of allowed time remaining for the RPC.

A nonnegative float indicating the length of allowed time in seconds remaining for the RPC to complete before it is considered to have timed out, or None if no deadline was specified for the RPC.

Client-Side Context ¶

Invocation-side utility object for an RPC.

Accesses the status code sent by the server.

This method blocks until the value is available.

The StatusCode value for the RPC.

Accesses the details sent by the server.

The details string of the RPC.

Accesses the initial metadata sent by the server.

The initial metadata .

Accesses the trailing metadata sent by the server.

The trailing metadata .

Client-Side Interceptor ¶

Describes an RPC to be invoked.

The method name of the RPC.

An optional duration of time in seconds to allow for the RPC.

Optional metadata to be transmitted to the service-side of the RPC.

An optional CallCredentials for the RPC.

An optional flag to enable wait_for_ready mechanism.

An element of grpc.compression, e.g. grpc.compression.Gzip.

Affords intercepting unary-unary invocations.

Intercepts a unary-unary invocation asynchronously.

continuation – A function that proceeds with the invocation by executing the next interceptor in chain or invoking the actual RPC on the underlying Channel. It is the interceptor’s responsibility to call it if it decides to move the RPC forward. The interceptor can use response_future = continuation(client_call_details, request) to continue with the RPC. continuation returns an object that is both a Call for the RPC and a Future. In the event of RPC completion, the return Call-Future’s result value will be the response message of the RPC. Should the event terminate with non-OK status, the returned Call-Future’s exception value will be an RpcError.

client_call_details – A ClientCallDetails object describing the outgoing RPC.

request – The request value for the RPC.

An object that is both a Call for the RPC and a Future. In the event of RPC completion, the return Call-Future’s result value will be the response message of the RPC. Should the event terminate with non-OK status, the returned Call-Future’s exception value will be an RpcError.

Affords intercepting unary-stream invocations.

Intercepts a unary-stream invocation.

continuation – A function that proceeds with the invocation by executing the next interceptor in chain or invoking the actual RPC on the underlying Channel. It is the interceptor’s responsibility to call it if it decides to move the RPC forward. The interceptor can use response_iterator = continuation(client_call_details, request) to continue with the RPC. continuation returns an object that is both a Call for the RPC and an iterator for response values. Drawing response values from the returned Call-iterator may raise RpcError indicating termination of the RPC with non-OK status.

An object that is both a Call for the RPC and an iterator of response values. Drawing response values from the returned Call-iterator may raise RpcError indicating termination of the RPC with non-OK status. This object should also fulfill the Future interface, though it may not.

Affords intercepting stream-unary invocations.

Intercepts a stream-unary invocation asynchronously.

continuation – A function that proceeds with the invocation by executing the next interceptor in chain or invoking the actual RPC on the underlying Channel. It is the interceptor’s responsibility to call it if it decides to move the RPC forward. The interceptor can use response_future = continuation(client_call_details, request_iterator) to continue with the RPC. continuation returns an object that is both a Call for the RPC and a Future. In the event of RPC completion, the return Call-Future’s result value will be the response message of the RPC. Should the event terminate with non-OK status, the returned Call-Future’s exception value will be an RpcError.

request_iterator – An iterator that yields request values for the RPC.

Affords intercepting stream-stream invocations.

Intercepts a stream-stream invocation.

continuation – A function that proceeds with the invocation by executing the next interceptor in chain or invoking the actual RPC on the underlying Channel. It is the interceptor’s responsibility to call it if it decides to move the RPC forward. The interceptor can use response_iterator = continuation(client_call_details, request_iterator) to continue with the RPC. continuation returns an object that is both a Call for the RPC and an iterator for response values. Drawing response values from the returned Call-iterator may raise RpcError indicating termination of the RPC with non-OK status.

Service-Side Context ¶

A context object passed to method implementations.

Raises an exception to terminate the RPC with a non-OK status.

The code and details passed as arguments will supercede any existing ones.

code – A StatusCode object to be sent to the client. It must not be StatusCode.OK.

details – A UTF-8-encodable string to be sent to the client upon termination of the RPC.

Exception – An exception is always raised to signal the abortion the RPC to the gRPC runtime.

The status passed as argument will supercede any existing status code, status message and trailing metadata.

status – A grpc.Status object. The status code in it must not be StatusCode.OK.

Gets the auth context for the call.

A map of strings to an iterable of bytes for each auth property.

Accesses the value to be used as status code upon RPC completion.

Accesses the value to be used as detail string upon RPC completion.

Disables compression for the next response message.

This method will override any compression configuration set during server creation or set on the call.

Accesses the metadata sent by the client.

The invocation metadata .

Identifies the peer that invoked the RPC being serviced.

A string identifying the peer that invoked the RPC being serviced. The string format is determined by gRPC runtime.

Gets one or more peer identity(s).

Equivalent to servicer_context.auth_context().get(servicer_context.peer_identity_key())

An iterable of the identities, or None if the call is not authenticated. Each identity is returned as a raw bytes type.

The auth property used to identify the peer.

For example, “x509_common_name” or “x509_subject_alternative_name” are used to identify an SSL peer.

The auth property (string) that indicates the peer identity, or None if the call is not authenticated.

Sends the initial metadata value to the client.

This method need not be called by implementations if they have no metadata to add to what the gRPC runtime will transmit.

initial_metadata – The initial metadata .

Sets the value to be used as status code upon RPC completion.

This method need not be called by method implementations if they wish the gRPC runtime to determine the status code of the RPC.

code – A StatusCode object to be sent to the client.

Set the compression algorithm to be used for the entire call.

compression – An element of grpc.compression, e.g. grpc.compression.Gzip.

Sets the value to be used as detail string upon RPC completion.

This method need not be called by method implementations if they have no details to transmit.

Sets the trailing metadata for the RPC.

Sets the trailing metadata to be sent upon completion of the RPC.

If this method is invoked multiple times throughout the lifetime of an RPC, the value supplied in the final invocation will be the value sent over the wire.

trailing_metadata – The trailing metadata .

Access value to be used as trailing metadata upon RPC completion.

The trailing metadata for the RPC.

Service-Side Handler ¶

An implementation of a single RPC method.

Whether the RPC supports exactly one request message or any arbitrary number of request messages.

Whether the RPC supports exactly one response message or any arbitrary number of response messages.

A callable deserializer that accepts a byte string and returns an object suitable to be passed to this object’s business logic, or None to indicate that this object’s business logic should be passed the raw request bytes.

A callable serializer that accepts an object produced by this object’s business logic and returns a byte string, or None to indicate that the byte strings produced by this object’s business logic should be transmitted on the wire as they are.

This object’s application-specific business logic as a callable value that takes a request value and a ServicerContext object and returns a response value. Only non-None if both request_streaming and response_streaming are False.

This object’s application-specific business logic as a callable value that takes a request value and a ServicerContext object and returns an iterator of response values. Only non-None if request_streaming is False and response_streaming is True.

This object’s application-specific business logic as a callable value that takes an iterator of request values and a ServicerContext object and returns a response value. Only non-None if request_streaming is True and response_streaming is False.

This object’s application-specific business logic as a callable value that takes an iterator of request values and a ServicerContext object and returns an iterator of response values. Only non-None if request_streaming and response_streaming are both True.

Describes an RPC that has just arrived for service.

The metadata sent by the client.

An implementation of arbitrarily many RPC methods.

Returns the handler for servicing the RPC.

handler_call_details – A HandlerCallDetails describing the RPC.

An RpcMethodHandler with which the RPC may be serviced if the implementation chooses to service this RPC, or None otherwise.

An implementation of RPC methods belonging to a service.

A service handles RPC methods with structured names of the form ‘/Service.Name/Service.Method’, where ‘Service.Name’ is the value returned by service_name(), and ‘Service.Method’ is the method name. A service can have multiple method names, but only a single service name.

Returns this service’s name.

The service name.

Service-Side Interceptor ¶

Affords intercepting incoming RPCs on the service-side.

Intercepts incoming RPCs before handing them over to a handler.

State can be passed from an interceptor to downstream interceptors via contextvars. The first interceptor is called from an empty contextvars.Context, and the same Context is used for downstream interceptors and for the final handler call. Note that there are no guarantees that interceptors and handlers will be called from the same thread.

continuation – A function that takes a HandlerCallDetails and proceeds to invoke the next interceptor in the chain, if any, or the RPC handler lookup logic, with the call details passed as an argument, and returns an RpcMethodHandler instance if the RPC is considered serviced, or None otherwise.

An RpcMethodHandler with which the RPC may be serviced if the interceptor chooses to service this RPC, or None otherwise.

Multi-Callable Interfaces ¶

Affords invoking a unary-unary RPC from client-side.

Synchronously invokes the underlying RPC.

timeout – An optional duration of time in seconds to allow for the RPC.

metadata – Optional metadata to be transmitted to the service-side of the RPC.

credentials – An optional CallCredentials for the RPC. Only valid for secure Channel.

wait_for_ready – An optional flag to enable wait_for_ready mechanism.

The response value for the RPC.

RpcError – Indicating that the RPC terminated with non-OK status. The raised RpcError will also be a Call for the RPC affording the RPC’s metadata, status code, and details.

Asynchronously invokes the underlying RPC.

timeout – An optional durating of time in seconds to allow for the RPC.

The response value for the RPC and a Call value for the RPC.

Affords invoking a unary-stream RPC from client-side.

Invokes the underlying RPC.

timeout – An optional duration of time in seconds to allow for the RPC. If None, the timeout is considered infinite.

metadata – An optional metadata to be transmitted to the service-side of the RPC.

An object that is a Call for the RPC, an iterator of response values, and a Future for the RPC. Drawing response values from the returned Call-iterator may raise RpcError indicating termination of the RPC with non-OK status.

Affords invoking a stream-unary RPC from client-side.

RpcError – Indicating that the RPC terminated with non-OK status. The raised RpcError will also implement grpc.Call, affording methods such as metadata, code, and details.

Asynchronously invokes the underlying RPC on the client.

Synchronously invokes the underlying RPC on the client.

The response value for the RPC and a Call object for the RPC.

Affords invoking a stream-stream RPC on client-side.

Invokes the underlying RPC on the client.

timeout – An optional duration of time in seconds to allow for the RPC. If not specified, the timeout is considered infinite.

Future Interfaces ¶

Indicates that a method call on a Future timed out.

Indicates that the computation underlying a Future was cancelled.

A representation of a computation in another control flow.

Computations represented by a Future may be yet to be begun, may be ongoing, or may have already completed.

Adds a function to be called at completion of the computation.

The callback will be passed this Future object describing the outcome of the computation. Callbacks will be invoked after the future is terminated, whether successfully or not.

If the computation has already completed, the callback will be called immediately.

Exceptions raised in the callback will be logged at ERROR level, but will not terminate any threads of execution.

fn – A callable taking this Future object as its single parameter.

Attempts to cancel the computation.

This method does not block.

Returns True if the computation was canceled.

Returns False under all other circumstances, for example:

computation has begun and could not be canceled.

computation has finished

to determine its state without blocking.

Describes whether the computation was cancelled.

Returns True if the computation was cancelled before its result became available.

computation was not cancelled.

computation’s result is available.

Describes whether the computation has taken place.

Returns True if the computation already executed or was cancelled. Returns False if the computation is scheduled for execution or currently executing. This is exactly opposite of the running() method’s result.

Return the exception raised by the computation.

This method may return immediately or may block.

timeout – The length of time in seconds to wait for the computation to terminate or be cancelled. If None, the call will block until the computations’s termination.

The exception raised by the computation, or None if the computation did not raise an exception.

FutureTimeoutError – If a timeout value is passed and the computation does not terminate within the allotted time.

FutureCancelledError – If the computation was cancelled.

Returns the result of the computation or raises its exception.

timeout – The length of time in seconds to wait for the computation to finish or be cancelled. If None, the call will block until the computations’s termination.

The return value of the computation.

Exception – If the computation raised an exception, this call will raise the same exception.

Describes whether the computation is taking place.

Returns True if the computation is scheduled for execution or currently executing.

Returns False if the computation already executed or was cancelled.

Access the traceback of the exception raised by the computation.

timeout – The length of time in seconds to wait for the computation to terminate or be cancelled. If None, the call will block until the computation’s termination.

The traceback of the exception raised by the computation, or None if the computation did not raise an exception.

Compression ¶

Indicates the compression method to be used for an RPC.

Do not use compression algorithm.

Use “Deflate” compression algorithm.

Use “Gzip” compression algorithm.

Runtime Protobuf Parsing ¶

Returns a module generated by the indicated .proto file.

THIS IS AN EXPERIMENTAL API.

Use this function to retrieve classes corresponding to message definitions in the .proto file.

To inspect the contents of the returned module, use the dir function. For example:

` protos = grpc.protos("foo.proto") print(dir(protos)) `

The returned module object corresponds to the _pb2.py file generated by protoc. The path is expected to be relative to an entry on sys.path and all transitive dependencies of the file should also be resolveable from an entry on sys.path.

To completely disable the machinery behind this function, set the GRPC_PYTHON_DISABLE_DYNAMIC_STUBS environment variable to “true”.

protobuf_path – The path to the .proto file on the filesystem. This path must be resolveable from an entry on sys.path and so must all of its transitive dependencies.

A module object corresponding to the message code for the indicated .proto file. Equivalent to a generated _pb2.py file.

Use this function to retrieve classes and functions corresponding to service definitions in the .proto file, including both stub and servicer definitions.

` services = grpc.services("foo.proto") print(dir(services)) `

The returned module object corresponds to the _pb2_grpc.py file generated by protoc. The path is expected to be relative to an entry on sys.path and all transitive dependencies of the file should also be resolveable from an entry on sys.path.

A module object corresponding to the stub/service code for the indicated .proto file. Equivalent to a generated _pb2_grpc.py file.

Returns a 2-tuple of modules corresponding to protos and services.

The return value of this function is equivalent to a call to protos and a call to services.

A 2-tuple of module objects corresponding to (protos(path), services(path)).

Have a Question?

If you have any question you can ask below or enter what you are looking for!

  • Programming /

How To Fix: TypeError: No positional arguments allowed' in python List object with gRPC

I have already looked at this post , which doesn’t answer my problem

Here is how my proto file looks like

proto message GetWarehousesRequest { CreateAttributes base_wh = 1; repeated CreateAttributes partnered_wh = 2; }

(i am not posting grpc method signatures because they are trivial)

Note how partnered_wh is an array.

In python i have this method

In the for loop i am getting error that No position arguments are allowed . I need to convert python List to gRPC array. What should be best way to do so? Can i just assign that list to object? or there is better way?

Avatar for davy.ai

September 27, 2023 at 7:36 pm

To convert a Python list to a gRPC array, you need to use the appropriate method provided by the generated gRPC class.

In your case, the partnered_wh field is repeated in the protobuf definition, which indicates that it represents an array. To add elements to this array in Python, you should use the extend method provided by the generated class.

Here’s how you can modify your code to correctly add elements from partnered_whs to the partnered_wh array:

By using the extend method, you can add all the elements in the partnered_whs list to the partnered_wh array in the request object.

This way, you won’t encounter the “No positional arguments are allowed” error and the list will be correctly converted to a gRPC array.

Comments are closed.

Send Downlink command as JSON via gRPC and Python with use of payload formatter

Hey, I’m trying to send a downlink command via gRPC and Python to an existing device. It works to a point, but I tried to send a JSON, which then should get processed via the payload formatter. The problem is that if I send the JSON as an utf-8 encoded string, it does not get passed through the payload format but gets enqueued directly to the device. I tried to assign the req.queue_item.object, but it gives me an error (“AttributeError: Assignment not allowed to message, map, or repeated field “object” in the protocol message object.”). Is there a way to send a downlink to chirpstack with a JSON so that the payload formatter can encode it for the device?

Are you testing this against ChirpStack v3 or v4?

Hey, We use ChirpStack v4 and the corresponding PyPI library.

@brocaar , is this a bug, or is this functionality not yet implemented?

Where in v3 you had to pass the JSON object as string, you must pass it as JSON object in v4 ( https://github.com/chirpstack/chirpstack/blob/master/api/proto/api/device.proto#L483 ).

@brocaar I know, but if I set it to either a python JSON object or a google.protobuf.Struct it returns:

And what do I do with the data field, I can’t let it be empty.

I’m not familiar with the Python API for Protobuf struct types, but maybe this could help you? dictionary - How do you create a Protobuf Struct from a Python Dict? - Stack Overflow

@brocaar I tried that before but same message:

I think there is something else wrong. Maybe the word object is conflicting with something in python? Or something went wrong with the code generation for python. But I honestly don’t know how to debug this.

Found the solution. If you use:

Instead of:

Then everything works.

python grpc assignment not allowed to field

  • Latest Articles
  • Top Articles
  • Posting/Update Guidelines
  • Article Help Forum

python grpc assignment not allowed to field

  • View Unanswered Questions
  • View All Questions
  • View C# questions
  • View C++ questions
  • View Javascript questions
  • View Visual Basic questions
  • View Python questions
  • CodeProject.AI Server
  • All Message Boards...
  • Running a Business
  • Sales / Marketing
  • Collaboration / Beta Testing
  • Work Issues
  • Design and Architecture
  • Artificial Intelligence
  • Internet of Things
  • ATL / WTL / STL
  • Managed C++/CLI
  • Objective-C and Swift
  • System Admin
  • Hosting and Servers
  • Linux Programming
  • .NET (Core and Framework)
  • Visual Basic
  • Web Development
  • Site Bugs / Suggestions
  • Spam and Abuse Watch
  • Competitions
  • The Insider Newsletter
  • The Daily Build Newsletter
  • Newsletter archive
  • CodeProject Stuff
  • Most Valuable Professionals
  • The Lounge  
  • The CodeProject Blog
  • Where I Am: Member Photos
  • The Insider News
  • The Weird & The Wonderful
  • What is 'CodeProject'?
  • General FAQ
  • Ask a Question
  • Bugs and Suggestions

python grpc assignment not allowed to field

gRPC, .NET 8.0 and Kestrel in Easy Samples

python grpc assignment not allowed to field

Web gRPC Under ASP.NET 8.0, Kestrel with HTML/JavaScript and Avalonia Clients

Image 1

This dedication is my farewell present to my good friends at Kahua.com including

  • Colin Whitlock - who on top of being a great CTO, is also a great manager, architect and developer in the company.
  • Jon Sinsel - an extremely sharp C# guru who very patiently introduced me to Uno Platform and Kahua code.
  • Adam Love - the best Web, Mobile wizard (also a great C# developer) without whose help, I'd still be figuring out things about deploying ASP.NET application.
  • Jonas Mayor - terrific C# software engineer who introduced me to IIS URL Rewrite module and ASP.NET middleware.

Introduction

gRPC is an abbreviation for "Google Remote Procedure Calls". It is a high performance multi-platform technology for communications between a server and clients.

Here are the gRPC advantages:

  • gRPC messages are much smaller than those of the text based protocols (REST and SOAP), correspondingly gRPC communications are much faster.
  • gRPC can be used for Web communications.
  • gRPC supports Server side streaming This is important, because many other popular Web protocols e.g. REST do not support streaming.
  • gRPC (except from a browser) supports Client side as well as the bidirectional streaming (both client and server exchanging information via established streams at the same time). gRPC in browser not supporting client side streaming is a pretty bad limitation that might require switching to other technologies e.g. SignalR for chatty clients.
  • Both Server and Client gRPC can be run virtually on any platform and use various different software languages including, but not limited to C#, Java, JavaScript, Python.
  • gRPC is very simple and easy to learn.

Kestrel and ASP.NET 8.0

The recommended .NET gRPC service is implemented as part of Kestrel server.

Kestrel is a Microsoft Web server written entirely in .NET Core and because of that it is 100% multiplatform.

Kestrel is great for handling ASP.NET and gRPC requests/responses, but misses some Web server features and because of that is often deployed behind another Web server which plays role of a reverse proxy for ASP and gRPC requests/responses.

On Windows the reverse proxy server is usually IIS while on Linux it can be Apache or anything else:

Image 3

The integration between IIS and Kestrel comes naturally in .NET 8.0 and requires almost no code change.

Avalonia is a great open source .NET framework for writing UI on multiple platforms (including Windows, MacOS, Linux, WebAssembly, Android and iOS) using C# and XAML.

On top of being multiplatform, Avalonia framework is considerably better and more powerful than WPF or any JavaScript/TypeScript framework.

Avalonia allows creating applications of great speed and quality and has very few differences in the way it behaves on various platforms.

Avalonia can be used for creating Web applications using WebAssembly.

The Main Purpose of the Article

This article provides easy and well explained samples for building and deploying gRPC services using IIS/Kestrel ASP.NET functionality on Windows and consuming them by various gRPC Clients. Here are the gRPC clients presented in the article:

  • C# Console Program (would work exactly the same in C# desktop applications on any platform).
  • HTML/JavaScript Web broser client.
  • C# Non-Blazor Avalonia WebAssembly client. The reason I prefer not using Blazor is because from different sources on the Web I read that non-Blazor technology for C# WebAssembly and its interaction with HTML/JavaScript is more stable.

Important Note on Using ASP.NET

I'd like underscore that ASP.NET is often used to generate the HTML/JavaScript pages on the fly.

For application speed sake and clarity reasons, I prefer using ASP.NET for providing backend services only without almost any HTML/JavaScript generation.

One exception to the rule above is - sometimes, I add the constant global configuration parameters to ASP.NET pages via code generation only at the initial state (when the page is loaded the first time).

The AWebPros.com Website Demonstrating the gRPC Samples running under IIS/Kestrel

Using the code described in this article, I built a Website ASP gRPC Samples demonstrating web HTML/JavaScript and Avalonia WebAssembly client with IIS/Kestrel web server.

This article concentrates primarily on gRPC related code.

My wonderful journey through building and deploying a real life APS.NET web site I plan to describe in future articles. In particular I plan covering the following topics:

  • WebAssembly, Avalonia and ASP.NET.
  • Installing Hosting Bundle so that your ASP.NET would run under IIS.
  • Using IIS/Kestrel in and out of hosting model.
  • Using Cors.
  • Obtaining and deploying a free SSL certificate so that your website would not be marked as insecure by Web browsers.
  • Wiring ASP.NET Response Compression for WebAssembly files to improve speed.
  • Deploying ASP.NET web sites using Publish.

No gRPC Client Streaming in Browser (unfortunately)

There is a known limitation of grpc-web (the only gRPC framework that can be used for gRPC browser based clients) - it allows only server side streaming ( gRPC-Web Streaming ).

No client streaming or bidirectional streaming is allowed.

Using gRPC over WebAssembly has appearance of allowing Client side and bidirectional streaming, but in fact it is not correct.

As we shall learn from the samples below, when you try to stream from a Web Browser client, the messages are not sent one by one, but instead they are accumulated on the client until the client indicates the end of streaming. Then all the accumulated messages are sent to the server together.

gRPC ASP.NET Code Samples

The source code.

The source code for this article is located under ASP.NET gRCP Samples .

In order to maximize the code reuse between various samples, I built an all encompassing solution - AspGrpcTests.sln (which you never have to open) and a number of filtered solutions (.slnf) files around it. The .slnf files filter in the functionality specific to each sample.

Kestrel only Code Sample

Opening and running the kestrel only solution.

Kestrel can be used without IIS as a stand-alone process or Windows service. This sample (located in GrpcKestrelOnlyImplementation.slnf solution filter) demonstrates gRPC communications between a Kestrel-only server running as a console process and a local C# console client.

To run this sample open GrpcKestrelOnlyImplementation.slnf in Visual Studio 2022. You can see the following projects and files in the solution explorer:

Image 4

GrpcServerProcess is the project containing the Kestrel server and ConsoleTestClient is the project to start the local gRPC C# client.

Start the server process first (by right-clicking GrpcServerProcess and selecting Debug->Run Without Debugging). This will start the Kestrel server as a process on your windows. Note, that since the output of the server in not in HTML format, it will start a browser displaying an error something like ( This local page can't be found ). Do not worry about it and do not kill the browser if you want your server to continue running.

Then start the console client (project ConsoleTestClient) in the similar fashion. Here is what will be printed on the client console:

There are five gRPC scenarios demo'ed by this sample:

  • Unary sample - client sends "Joe Doe" string to the server and it returns "Hello Joe Doe!".
  • Streaming server sample - client sends single string ("Joe Doe") and returns multiple greetings.
  • Streaming server sample with error - same as the streaming server sample above, only the server throws an RpcException in the middle of the stream (after the 11th iteration).
  • Streaming client sample - client send multiple strings ("Client_1", "Client_2" and "Client_3") and the server concatenates them and returns the "Client_1, Client_2, Client_3" string.
  • Bidirectional streaming sample - the client sends 3 requests within ("Client_1", "Client_2" and "Client_3") and the server responds with 4 responses for each of the client requests (everything is happening in simultaneously - new client requests can arrive while the server responds to the old ones).

A Note on the Code Overview

Since similar or identical code is used in the rest of the samples, I will provide a very detailed review of the gRPC server and client code in this sample, while in the future samples, I'll be only emphasizing the differences with the current code.

Source Code Overview

The source code for this sample consists of 4 projects:

  • GrpcServerProcess - starting and running Kestrel server.
  • GreeterImpl - a re-usable library containing the gRPC server functionality implementation (GrpcServerProcess depends on it).
  • Protos - containing the Greeter.proto gRPC proto file shared between the server (via GreeterImpl) and the client.
  • ConsoleTestClient - the console client for running all the client gRPC tests against the server (it depends on Protos project as well).

The project dependencies are reflected on the diagram below:

Image 5

Protos project contains Greeter.proto file defining gRPC protos for the gRPC methods:

All the Greeter methods take HelloRequest message(s) as requests and return HelloReply messages as replies. I could have used built-in string protobuf Type for both, but wanted to show a more complex example with request and reply types defined in the proto file.

Note that there is an integer specified next to a field within HelloRequest and HelloReply protos, e.g.:

This integer should uniquely define a protobuf field, so that if new fields are added to the type , they should have different integers - in that case, the new expanded type will be backward compatible.

The most interesting server code is located within GreeterImplementation.cs file under the reusable GreeterImpl project.

Take a look at GreeterImpl.csproj file. It shows how to add a reference to a proto file contained by a different project:

We simply provide a relative path to the file.

The GrpcServices="Server" means that the server skeleton will be generated for the proto methods. Note that GreeterImpl project also has a reference to Grpc.AspNetCore package which has references needs to the generated the server skeleton.

GreeterImplementation class of GreeterImpl project inherits from the generated skeleton simple.Greeter.GreeterBase class. It provides overriding implementations for all the gRPC server methods, e.g here is the override for the simplest - single request/single reply SayHello(...) method:

GrpcServerProcess is the actual project that starts Kestrel server supporting the gRPC method implementations defined within GreeterImplementations class.

The local server port is defined within its appsettings.json file:

The rest of its functionality is contained within Program.cs file:

ConsoleTestClient project also references Greeter.proto file but with GrpcServices="Client" : That instructs the Visual Studio to generate client proxies for Greeter methods.

ConsoleTestClient also needs to provide references to Grpc.Net.Client, Google.Protobuf and Grpc.Tools packages:

The really interesting custom code is server implementations of gRPC methods and client calls to those methods. Server implementations are contained within GreeterImplementations.cs file (under the re-usable GreeterImpl project) and client calls are contained within Program.cs file of the ConsoleTestClient projects.

In the subsequent sections below I shall explain those methods one by one.

Single Request / Single Reply SayHello(...) method

This is the simplest method to implement and to call (since there is no either server or client side streaming).

Here is the protobuf code for this method from Greeter.proto file located under Protos project:

Here is the client code (from ConsoleTestClient/Program.cs file):

The code at the top of the snippet above connects the gRPC client to the grpc server at "https://localhost:55003" url and creates the greeterGrpcClient object to call the server methods.

The server call itself takes only one line:

We create the HelloRequest object setting its name to "Joe Doe", send it over to the server and wait for the reply.

reply.Msg will contain the "Hello Joe Doe!" greeting string.

The server implementation (located within GreeterImplementation.cs file) is also very simple:

The client call will result in the following msg printed to the console:

Server Streaming Samples

There are two Server Streaming samples - one plain ServerStreamHelloReplies(...) method and the other one with server throwing an RpcExeption in the middle of the streaming responses being sent back to the client ServerStreamHelloRepliesWithError(...) .

Here is the protobuf code for these two methods:

Here is the client code for the plain method (without server error):

The result of this client method call will be a stream of messages printed to the console:

The client code for the server streaming with error is very similar, only its is encased within try/catch block:

And here is what it prints to the console:

The server throws an error after the 11th iteration and the error message intended for the client is "Error Status Detail (for the client)" (the server can write another, more detailed, error message to its log).

Now let us take a look at the server implementations of the server streaming methods within GreeterImplementation.cs file:

Both methods call ServerStreamHelloRepliesImp(...) method, one passing the argument throwException set to false and the other set to true .

Note that the line:

serves to cancel the server streaming from the client side. Client side cancellation will be demo'ed later when we discuss the web clients.

Client Streaming Sample

Next sample (method Greeter.ClientStreamHelloRequests(...) ) demonstrates async streaming from the client, accumulating the results on the server and returning the single value result to the client after the client streaming ended.

Here is the protobuf declaration of this methods:

Here is the client code:

The server returns string "Hello " followed by the comma separated concatenation of the messages from the client:

Here is the server code:

Note, that the server receives each of the client messages as they are streamed, without waiting for the client streaming to end. You can observe it by running the server in a debugger and putting a breakpoint within the await foreach(...) loop.

Bidirectional Streaming Sample

Finally we came the most interesting and complex sample - the one that demonstrates streaming both client requests and server replies simultaneusly: the server does not wait for the client to finish its streaming it starts replying after each client request arrives.

The protobuf method is called Greeter.ClientAndServerStreamingTest(...) :

Note that both requests and replies are streamed.

Here is the client implementation of calling bidirectional streaming functionality:

The readTask defined at the top will be used to get the streaming replies, one by one.

Here is what the client prints to console:

For every string coming from the client, the server sends back 4 replies e.g. for Client_1, the replies will be Client_1_1, Client_1_2, Client_1_3 and Client_1_4.

Note that the interval between streaming client messages to the server is pretty large - 1 second and yet, there is almost no delay in server replies. This is because the server starts replying after the first client message is received and continues replying without waiting for the client streaming to be completed.

This is what the real bi-directional streaming is and unfortunately it will NOT work from the browser as will be explained below.

Overview of Browser Based Code Sample Code Samples

The rest of the ASP.NET gRPC code samples will be browser based. One sample demonstrates the HTML/JavaScript using gRPC to exchange information with the server and the other Avalonia WebAssembly.

The server gRPC code for those samples will be exactly the same as in the previous sample - located within GreeterImplementation.cs file under GreeterImpl project. Because of that we shall concentrate primarily on the client code and ASP.NET specific server code.

HTML/JavaScript ASP.NET gRPC Sample

Running the sample.

Start the solution filter AspGrpcServerWithRazorClient.slnf. Make AspGrpcServerWithRazorClient project to be your startup project. Build the project and run it under the debugger.

Here is the page you'll see:

Image 6

You can try changing the name (or leaving it set to "Nick"), then clicking "Get Single Greeting" button and you'll get "Hello Nick!!!" printed in the browser:

Image 7

Now try clicking "Get Multiple Greetings" button. You will see multiple greeting streaming from the server from "Hello Nick 1" to "Hello Nick 20" and at the end it will print "STREAMING ENDED" (if you let it run to the end):

Image 8

You can also cancel the server streaming at any point by pressing button "Cancel Streaming".

Pressing button "Get Multiple Greetings with ERROR" will call the on the server method that will throw an RpcException after 11th iteration. Here is how the resulting error is displayed:

Image 9

Creating the ASP.NET Project for Hosting the Sample

I created the ASP.NET project AspGrpcServerWithRazorClient.csproj by choosing "ASP.NET Core Web App (Razor Pages)" project type:

Image 10

Then I modified its Program.cs, Index.cshtml and _Layout.cshtml as will be detailed below.

Generating JavaScript Client Proxies from Protobuf Code

As a prerequisite for everything that follows, please, install nodeJS and npm e.g. by going to Node JS Install , downloading the node .msi installer and running it on your windows machine.

In order to build the server you need to

  • Install protoc protobuffer compiler e.g. from Protoc Compiler Download by downloading and unzipping protoc-26.1-win64.zip (or some other file depending on your machine). Make sure protoc.exe is in your path.
  • Generate the JavaScript client proxies from Greeter.proto protobuf file using protoc compiler. Protoc will generate nodeJS JavaScript proxies. Here is the command that needs to be run from a command line from inside the Protos folder (of the Protos project) to generate the client proxies: protoc -I=. Greeter.proto --js_out=import_style=commonjs:..\AspGrpcServerWithRazorClient\wwwroot\dist --grpc-web_out=import_style=commonjs,mode=grpcwebtext:..\AspGrpcServerWithRazorClient\wwwroot\dist This line is also contained in README.txt file within the same folder.

Image 11

  • There is a tiny JavaScript file AspGrpcServerWithRazorClient/wwwroot/dist/client.js that refers to all the functionality that the JavaScript client needs from the generated Greeter_..._pb.js files: JavaScript const { HelloRequest, HelloReply } = require( ' ./Greeter_pb.js' ); const { GreeterClient } = require( ' ./Greeter_grpc_web_pb.js' ); global.HelloRequest = HelloRequest; global.HelloReply = HelloReply; global.GreeterClient = GreeterClient; This file is used by webpack for generating the main.js file that can be used by the browser client.
  • In order to use webpack file generation, we need to create webpack.config.js file at the project level. Here is its content: JavaScript const path = require( ' path' ); module.exports = { mode: ' development' , entry: ' ./wwwroot/dist/client.js' , output: { path: path.resolve(__dirname, ' wwwroot/dist' ), filename: ' main.js' , }, }; It will instruct webpack to take client.js and every file it depends on and based on them create main.js file (located under the same dist folder) which can be used by the JavaScript browser clients.

Image 13

HTML/JavaScript Client Code Overview

HTML/JavaScript client code that uses the proxies generated in the previous subsection is located within AspGrpcServerWithRazorClient/Pages/Index.cshtml file. The file is virtually all HTML/JavaScript with no ASP code generation.

The HTML part of the file defines labels, buttons and divs (as placeholders for adding text):

Then two modules are added -

  • main.js file generated in the previous subsection. main.js module is used get the client proxy code).
  • jquery.min.js - for finding HTML tree nodes and modifying them.

And then finally there is JavaScript client code within <script type="text/javascript"> HTML tag.

Client Code to Create the gRPC Greeter Client

After creating the client greeterServiceClient , we use it for gRPC service calls.

Calling Single Request / Single Reply SayHello(...) Service from JavaScript Client

Here is how we call SayHello(...) service from JavaScript client:

This code itself is assigned using jQuery to be a callback on the "#GetSingleGreetingButton" click:

Calling Streaming gRPC Services form the Client

For server streaming calls we define a global variable var stream = null; and then use it to call the streaming services and to cancel them if needed.

For the sake of the code reuse there is a single JavaScript getStreamedGreetings(greeterServiceClient, throwError) method whose second argument is a Boolean flag - that should be set to true to call the gRPC streaming service that throws an error after the 11th iteration and false for the one that allows the streaming service to run all the way to the end.

Here is how streaming service invocation callbacks are assigned to the corresponding buttons:

Here is the getStreamedGreetings(...) method implementation (with detailed comments):

Canceling Server Streaming

All one needs to do is to cancel a server stream is to call stream.cancel("Cancellation Message") .

ASP.NET Code for Building and Starting ASP.NET Server

This code is located within well documented Program.cs file under AspGrpcServerWithRazorClient project:

ASP.NET Avalonia/WebAssembly gRPC Code Sample

To run the sample, please, open AspGrpcWithAvaloniaClients.slnf solution filter file, make AspGrpcServer the start-up project, then re-build it and start it.

Here is the screen you are going to see (after a second or too):

Image 15

The upper two samples (request/reply and server samples) will behave almost exactly the same as those of the previous section:

Image 16

The two bottom samples correspond to Client streaming and bi-directional client-server streaming and the purpose is to show that they will NOT work correctly in browser.

Indeed, if you press "Test Streaming Client" or "Test Streaming Client and Server" buttons, the server will get the messages and start responding only when the client stream is completed (it is 5 seconds for Streaming Client sample and 3 second for bi-directional sample). Which essentially means that client streaming is not working (even though C# generates client proxies for those protobuf methods).

Creating Client C# Avalonia Projects

To create an Avalonia WebAssembly project I use instructions from Creating Avalonia Web Assembly Project :

  • I install wasm-tools (or make sure they are installed) by running dotnet workload install wasm-tools from a command line.
  • I update to the latest avalonia dotnet templates by running command: dotnet new install avalonia.templates
  • I create a folder for the project (in my case it is called AvaGrpcClient) and cd to it using the command line.
  • From within that folder, I run from the command line: dotnet new avalonia.xplat
  • This will create the shared project AvaGrpcClient (within the same-named folder) and a number of platform specific projects.
  • I remove most of the platform specific projects leaving only AvaGrpcClient.Browser (for building the Avalonia WebAssembly bundle) and AvaGrpcClient.Display (for debugging and faster prototyping if needed).

Client Avalonia Code

In order for the project AvaGrpcClient to generate the gRPC client proxies, I add a reference to the protobuf file to AvaGrpcClient.csproj file with GrpcServices flag set to Client:

I also add references to packages required by Grpc including Grpc.Net.Client.Web package needed specifically for the grpc to work in a browser:

Almost all Sample specific client code is located within MainView.xaml.cs and MainView.xaml files. MainView.xaml specifies the visual layout while all the code interacting with the server is inside MainView.xaml.cs file.

The connection to the client is established within MainView class constructor:

Note the CommonData.Url static string property. It should contain the URL for connected to the Grpc calls ( nn my case it is the same as ASP.NET server URL).

This CommonData.Url property is set to the first argument passed to the Program.Main(...) method contained in AvaGrpcClient.Browser solution (solution that actually creates WebAssembly browser code as a number of .wasm files):

Note also that calling the following code

essentially replaces an HTML element with id "out" by the Avalonia Browser application (in our case it is MainView object instance).

The callbacks fired when the corresponding buttons are pressed are defined as methods within MainView.xaml.cs file.

Here is the code for calling Single Request/Single Response (Unary) service SayHello from the client:

where GreetingName property is the Text value from the TextBox defined in MainView.xaml file:

Here is the document client code for testing server streaming:

Code for testing server streaming with error is exactly the same, only calls a different service ServerStreamHelloRepliesWithError(...) :

The method below cancels server streaming from the client

The next method demonstrates using the Client Streaming API. Because we work in C#, the Client Streaming API has been generated, and can be used - but, unfortunately it does not do the streaming from the browser. It waits until the client streaming is finished and then sends all the accumulated messages together:

And here is the code demonstrating bi-directional (client and server) streaming API suffering from the same problem (there is no Client side streaming from the browser - the browser accumulates client messages and sends the all together one the client closes the 'stream'):

ASP.NET Server Code

The server ASP.NET code is located within AspGrpcServer project.

There are two things to know about the project:

Image 17

  • There is a post-build event defined within the AspGrpcServer project (see the bottom of AspGrpcServer.csproj file). This event copies AppBundle/_framework folder created by AvaGrpcClient.Browser build over to AspGrpcServer/wwwroot/_framework folder. Note - this folder (_framework) should be ignored by the version control tool.

I modified the Shared/_Layout.cshtml code to be simpler and also I modified the Index.cshtml file to contain a <div id="out"> which will be replaced by Avalonia WebAssembly MainView object instance (as was explained above).

Here is the code for Index.cshtml:

On the last line of the above code - note that we are loading mainForAvalonia.js module. This module/file contains the JavaScript code that actually creates the Wasm and runs the wasm project in the browser.

Here is the JavaScript code contained inside mainForAvalonia.js file:

Note the last line - this is where we we pass the current server URL to server also as the URL for creating gRPC client communication channel.

This is an article in which I provide easy samples and detailed explanations of all the use-cases for gRCP communications between various clients (including C# Console, HTML/JavaScritp and C# in Browser via WebAssembly clients), and gRPC-enabled ASP.NET server.

This article, along with any associated source code and files, is licensed under The MIT License

LinkedIn

Comments and Discussions

python grpc assignment not allowed to field

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

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

ValueError: mutable default <class 'mitmproxy.contentviews.grpc.ProtoParser.ParserOptions'> for field parser_options is not allowed: use default_factory on python 3.11 #5474

@rathann

rathann commented Jul 22, 2022

  • 👍 2 reactions

@rathann

mhils commented Jul 22, 2022

Sorry, something went wrong.

@mhils

lampuiho commented Jun 4, 2023

Mhils commented jun 4, 2023.

Successfully merging a pull request may close this issue.

@mhils

IMAGES

  1. The Beginner's Guide to gRPC with Examples

    python grpc assignment not allowed to field

  2. Implementing gRPC In Python: A Step-by-step Guide (2023)

    python grpc assignment not allowed to field

  3. gRPC + Python + Microservices Complete tutorial With realife Usecase

    python grpc assignment not allowed to field

  4. Python gRPC Tutorial

    python grpc assignment not allowed to field

  5. gRPC 101 : Run your Go Code in Python

    python grpc assignment not allowed to field

  6. gRPC + Python 入门到生产环境

    python grpc assignment not allowed to field

VIDEO

  1. Avengers Superhero Story, Marvel's Spider Man 2, Hulk, Iron Man, Captain America, Venom

  2. (2024) Easy to learn the 100 Civics Questions for US Citizenship Test by 9 Groups

  3. 🚀 Terraform-EKS-Python-gRPC

  4. PYTHON OPERATORS ASSIGNMENT OPREATORS

  5. Keynote: Beginning gRPC with Python con Andrés Pineda

  6. How To Use EXCEPTION GROUPS In Python 3.11 (NEW FEATURE!)

COMMENTS

  1. python

    You cannot assign a value to an embedded message field. Instead, assigning a value to any field within the child message implies setting the message field in the parent. So I'm assuming this should work: task = yacc.task() task.id = 1000 task.msg = u"test" ptask = yacc.task_info() ptask.task.id = task.id ptask.task.msg = task.msg

  2. python

    As per the documentation, you aren't able to directly assign to a repeated field. In this case, you can call extend to add all of the elements in the list to the field. Similarly, for adding a single value, use append(), e.g. person.id.append(1). This applies for any protobuf repeated fields.

  3. Question: How to set oneof fields in python? #5012

    Protobuf python does not support assignment for message field, even it is a normal message field instead of oneof, "test.a =" is still not allowed. "You cannot assign a value to an embedded message field. Instead, assigning a value to any field within the child message implies setting the message field in the parent. " :

  4. Quick start

    gRPC tools. Python's gRPC tools include the protocol buffer compiler protoc and the special plugin for generating server and client code from .proto service definitions. For the first part of our quick-start example, we've already generated the server and client stubs from helloworld.proto, but you'll need the tools for the rest of our quick start, as well as later tutorials and your own ...

  5. gRPC with Python

    Each field must be annotated with one of the following modifiers: repeated: the field may be repeated any number of times (including zero). optional: the field may or may not be set. If an optional field value isn't set, a default value is used. required: a value for the field must be provided, otherwise the message will be considered ...

  6. Basics tutorial

    A basic tutorial introduction to gRPC in Python. Then you define rpc methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the RouteGuide service:. A simple RPC where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function ...

  7. Python Generated Code Guide

    The protocol buffer compiler generates a class called Foo, which subclasses google.protobuf.Message.The class is a concrete class; no abstract methods are left unimplemented. Unlike C++ and Java, Python generated code is unaffected by the optimize_for option in the .proto file; in effect, all Python code is optimized for code size.. If the message's name is a Python keyword, then its class ...

  8. exporting histogram via GRPC results in error: Assignment not allowed

    Environment Python runtime: 3.9.9 OS: MacOS Monterey (version 12.2.1) Arch: M1 (ARM) Steps to reproduce write a python script to test histogram using opentelemetry: from opentelemetry.sdk._metrics....

  9. A Beginner's Guide to gRPC with Python

    Follow the steps below to set up a Python environment for gRPC 1: Quick Setup: cd path/to/my/folder. python -m venv .venv. source .venv/bin/activate. python -m pip install --upgrade pip. Install gRPC and gRPC Tools: python -m pip install grpcio. python -m pip install grpcio-tools.

  10. gRPC

    Use this function to retrieve classes and functions corresponding to service definitions in the .proto file, including both stub and servicer definitions. To inspect the contents of the returned module, use the dir function. For example: ` services = grpc.services("foo.proto") print(dir(services)) `.

  11. AttributeError: Assignment not allowed to repeated field "geo_target

    AttributeError: Assignment not allowed to repeated field "geo_target_constants" in protocol message object. Can anyone tell me how i can fix this "Assignment not Allowed to repeated field" error? Thanks!

  12. Python使用Protobuf&&如何赋值&&如何正反序列化

    那么,在python中应该怎么赋值呢? 错误示例: search_service. uid = 0. 如果还是和之前一样的赋值,就会报错. AttributeError: Assignment not allowed to repeated field "uid" in protocol message object. 正确示例: search_service. uid. append (1) search_service. uid. append (2)

  13. python

    AttributeError: Assignment not allowed to composite field "delete_from_row" in protocol message object. According to the protobuf docs, you should set a oneof field by setting one of the child fields. So a DeleteFromFamily mutation should be created this way:

  14. How To Fix: TypeError: No positional arguments allowed' in python List

    To convert a Python list to a gRPC array, you need to use the appropriate method provided by the generated gRPC class. In your case, the partnered_wh field is repeated in the protobuf definition, which indicates that it represents an array. To add elements to this array in Python, you should use the extend method provided by the generated class.

  15. Repeated maps not allowed? · Issue #3672

    Milestone. No milestone. Development. No branches or pull requests. 1 participant. I have this line in my proto: repeated map<string, string> dependencies = 4; I get this error: Field labels (required/optional/repeated) are not allowed on map fields.

  16. How to set a protobuf Timestamp field in python?

    AttributeError: Assignment not allowed to composite field "tstamp" in protocol message object. Can anyone explain to me why this isn't working as I am nonplussed. python

  17. Send Downlink command as JSON via gRPC and Python with use of payload

    Hey, I'm trying to send a downlink command via gRPC and Python to an existing device. It works to a point, but I tried to send a JSON, which then should get processed via the payload formatter. The problem is that if I send the JSON as an utf-8 encoded string, it does not get passed through the payload format but gets enqueued directly to the device. I tried to assign the req.queue_item ...

  18. Assignment not allowed to repeated field #524

    What is your question? I was trying to Generate Keyword Ideas by using Google Ads API and I was following this post. However, on running the code I received the following error: Traceback (most recent call last): File ".\keywords.py", li...

  19. protocol buffers

    Traceback (most recent call last): File "x.py", line 8, in <module> x.data['a'] = y ValueError: Direct assignment of submessage not allowed How can I work around this problem? python

  20. gRPC, .NET 8.0 and Kestrel in Easy Samples

    Both Server and Client gRPC can be run virtually on any platform and use various different software languages including, but not limited to C#, Java, JavaScript, Python. gRPC is very simple and easy to learn. Kestrel and ASP.NET 8.0. The recommended .NET gRPC service is implemented as part of Kestrel server.

  21. Missing fields when numeric values have ZERO as their value or strings

    I am facing an interesting problem when using a GRPC service written in Python. It seems like whenever the service is returning ZERO as the value for a numeric field or an empty string for a string field it is not setting some properties of the object. That is a problem because that results in uncomplete objects.

  22. ValueError: mutable default <class 'mitmproxy.contentviews.grpc

    * use default_factory for field parser_options When running mitmproxy under python 3.11, the following exception is thrown otherwise: ``` ValueError: mutable default <class 'mitmproxy.contentviews.grpc.ProtoParser.ParserOptions'> for field parser_options is not allowed: use default_factory ``` Fixes #5474. * add changelog for #5474