Search code examples
pythonjsonserializationprotocol-buffersgrpc

Serializing object in gRPC


I want to send some data (payload) from gRPC server(localhost) to my client (localhost). I call an API (IMDB -> top 250 movies) and saved my data in a JSON file. Server response must be the IMDB top 250 movies (As JSON Object) But I couldn't do that

here is my .proto file:

syntax = "proto3";

// Incoming request from client
message get_top_250_movies{
    optional string name = 1;
}

// Response to be returned by API service
message top_movies{
    optional string response = 1;

}

// Service definition for MoviesData
service MoviesData{

    // get movies method definition 
    rpc get_movies(get_top_250_movies) returns (top_movies) {};
}

Client Program:

import grpc
import json
import movie_service_pb2 as pb2
import movie_service_pb2_grpc as pb2_grpc



with open('Top250Movies.json') as f:
    data = json.load(f)


class FetchMovies:

    def __init__(self) -> None:
        self.channel = grpc.insecure_channel('localhost:50051')
        self.stub = pb2_grpc.MoviesDataStub(self.channel)

    def get_movies(self):
        
        response = self.stub.get_movies(json.dumps(data))
        return response


if __name__ == "__main__":
    client = FetchMovies()
    print(client.get_movies())

Server program:

import json
from concurrent import futures
import movie_service_pb2 as pb2
import movie_service_pb2_grpc as pb2_grpc



class MoviesDataService(pb2_grpc.MoviesDataServicer):

    def get_movies(self, request, context):

        with open('Top250Movies.json') as f:
            data = json.load(f)

        return pb2.get_top_250_movies(f'{request.name}')


def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    pb2_grpc.add_MoviesDataServicer_to_server(MoviesDataService(), server)
    server.add_insecure_port("localhost:50051")
    server.start()
    server.wait_for_termination()




if __name__ == "__main__":
    print('running the gRPC server')
    serve()

I just need to take any request and send back a response that contains a list of movies that I saved in a json file (Send all 250 movies as a JSON object to client) json.dumps(pythonObject) will face an error: it couldn't serialized that and expected str | bytes or ...

thanks for your help


Solution

  • The problem was .proto file, I fixed it myself like this:

    syntax = "proto3";
    
    
    message MovieRequest {
        // Send a Request to Server
        string movie_list = 1;
    }
    
    
    // this message solved my problem
    message MovieList {
        // Get Movie data includes: rank, title, imDbRating, imDbRatingCount
        string rank = 1;
        string title = 2;
        string imDbRating = 3;
        string imDbRatingCount = 4;
    }
    
    
    message MovieResponse {
        // Get a List of MovieList Message; field_name == movies
        repeated MovieList movies = 1;
    }
    
    service Movies{
        // Run method get_movies with MovieRequest parameter and return MovieResponse
        rpc get_movies(MovieRequest) returns (MovieResponse);
    }