gRPC-Methods used when dealing with protocol buffers types in Python CopyFrom, Extend

If you use gRPC with python, you will be using the protocolbuffer (pb2) type. There are some points to be aware of when dealing with this protocolbuffer type, so I will summarize it in the article.

Protocol buffer type assignment processing using CopyFrom method

For example, if you have the following proto definition: Simple design with one method.

user.proto



service UserService {
  rpc GetUser(GetUserRequest) returns (User) {}
}

message Size {
  int32 height = 1;
  int32 weight = 2;
}

message User {
  string id = 1;
  string name = 2;
  Size size = 3;
}

message GetUserRequest {
  string user_id = 1;
}

The following is a server-side implementation example of UserService using the above proto file.

import user_pb2

class UserService():
  def GetUser(self, request, context):
    #get the user of db
    db_user = db.get(request.user_id)
    
    #Define size and add value
    size = user_pb2.Size()
    size.height = db_user.height
    size.weight = db_user.weight

    #Define user, add value and return
    user = user_pb2.User()
    user.id = db_user.id
    user.name = db_user.name
    user.size = size

    return user

When I execute the above GetUser method, I get an error with TypeError. The problem is the penultimate line of code ʻuser.size = size`.

The size, which is an object type of Size type, is the same as the size type defined in User type, but if you assign it as it is, an error will occur. The method used here is CopyFrom. By rewriting the problem part of the above code as follows, the code will be executed without TypeError.

import user_pb2

class UserService():
  def GetUser(self, request, context):
    #get the user of db
    db_user = db.get(request.user_id)
    
    #Define size and add value
    size = user_pb2.Size()
    size.height = db_user.height
    size.weight = db_user.weight

    #Define user, add value and return
    user = user_pb2.User()
    user.id = db_user.id
    user.name = db_user.name
    user.size.CopyFrom(size)

    return user

Even if you compare using the Type method, it is difficult to notice because the size object is a Size type, but when assigning it as a protocol buffer type, you can not assign it correctly unless you use CopyFrom.

Repeated type assignment using Extend

Even with repeated definitions, there are some points to be aware of when assigning. This is explained using the following proto file, which is a rewrite of the previous UserService.

User.proto



service UserService {
  rpc GetUser(GetUserRequest) returns (User) {}
}

message Item {
  string id = 1;
  string name = 2;
}

message User {
  string id = 1;
  string name = 2;
  repeated Item items = 3;
}

message GetUserRequest {
  string user_id = 1;
}

I changed size to a repeated type called items. Below is the UserService code.

import user_pb2

class UserService():
  def GetUser(self, request, context):
    #get the user of db
    db_user = db.get(request.user_id)
    
    #Define multiple items and create an items list
    item1 = user_pb2.Item()
    item1.id = '1'
    item1.name = 'item1'

    item2 = user_pb2.Item()
    item2.id = '2'
    item2.name = 'item2'

    items = [item1, item2]

    #Define user, add value and return
    user = user_pb2.User()
    user.id = db_user.id
    user.name = db_user.name
    user.items = items

    return user

When I run the above code, I still get a TypeError. The problem is also ʻuser.items = items`. Use the extend method to assign to a repeated field.

    user.items.extend(items)

It is possible to set the value to the array type by using extend as described above.

I checked on google's official page etc. why it is necessary to handle it like this, but it was not explained well. Protocol buffer seems to have a habit on Python, so use it with caution!

Recommended Posts

gRPC-Methods used when dealing with protocol buffers types in Python CopyFrom, Extend
Precautions when dealing with ROS MultiArray types in Python
Precautions when dealing with control structures in Python 2.6
Character encoding when dealing with files in Python 3
Japanese output when dealing with python in visual studio
Read Protocol Buffers data in Python3
Until dealing with python in Atom
Tips for dealing with binaries in Python
Put protocol buffers into sqlite with python
Dealing with "years and months" in Python
[Python] Dealing with multiple call errors in ray.init
Japanese can be used with Python in Docker environment
Mailbox selection when retrieving Gmail with imaplib in python
Organize types in Python
Problem not knowing parameters when dealing with Blender from Python
Things to keep in mind when using Python with AtCoder
Scripts that can be used when using bottle in Python
Things to keep in mind when using cgi with python.
Here's a summary of things that might be useful when dealing with complex numbers in Python
Extend python in C ++ (Boost.NumPy)
Scraping with selenium in Python
Use Measurement Protocol in Python
Working with LibreOffice in Python
Scraping with chromedriver in python
Debugging with pdb in Python
Working with sounds in Python
Scraping with Selenium in Python
Scraping with Tor in Python
Tweet with image in Python
Attention when os.mkdir in Python
Combined with permutations in Python
Error when playing with python
New features in Python 3.9 (1)-Union operators can be used in dictionary types