{"id":18750,"date":"2017-09-26T12:15:15","date_gmt":"2017-09-26T09:15:15","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=18750"},"modified":"2017-09-21T16:17:29","modified_gmt":"2017-09-21T13:17:29","slug":"using-grpc-python","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/","title":{"rendered":"Using gRPC in Python"},"content":{"rendered":"<p><a href=\"https:\/\/grpc.io\/about\/\">gRPC<\/a> is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses <a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/overview\">protocol buffers<\/a> (<code>protobuf<\/code>) as the underlying data serialization framework. It is an alternative to other language-neutral RPC frameworks such as <a href=\"https:\/\/thrift.apache.org\/\">Apache Thrift<\/a> and <a href=\"https:\/\/avro.apache.org\/docs\/current\/\">Apache Arvo<\/a>.<\/p>\n<p>In the first part of this series on using gRPC in Python, we will implement a gRPC service in Python. Our gRPC service will be a <code>users<\/code> service that will expose two functionalities: user signup and getting user details. In our fictional scenario, we will be interacting with this gRPC service directly from a command-line program and also from an HTTP web application.<\/p>\n<p>Some of the gRPC concepts we will explore in this article are:<\/p>\n<ul>\n<li>Streaming responses<\/li>\n<li>Setting client-side metadata<\/li>\n<li>Client-side timeouts<\/li>\n<\/ul>\n<p>We will be using Python 3.5 for our demos in the article. The <a href=\"https:\/\/github.com\/amitsaha\/python-grpc-demo\">git repository<\/a> has all the code listings we will be discussing in this article in the subdirectory <code>demo1<\/code>.<\/p>\n<h2>Service Specification<\/h2>\n<p>The first step to implementing a gRPC server is to describe the server\u2019s <code>interface<\/code>. The interface of the service is defined by the <code>functions<\/code> it exposes and the input and output <code>messages<\/code>. Our example service is called <code>Users<\/code> and defines one function to create a user and another to fetch user details. The following defines the service <code>Users<\/code> with two functions via <code>protobuf<\/code>:<\/p>\n<pre class=\"brush:py\">\/\/ users.proto\r\nsyntax = \"proto3\"; \r\nimport \"users_types.proto\";\r\nservice Users { \r\n  rpc CreateUser (users.CreateUserRequest) returns (users.CreateUserResult); \r\n  rpc GetUsers (users.GetUsersRequest) returns (stream  users.GetUsersResult); \r\n}<\/pre>\n<p><code>syntax \"proto3\"<\/code> declares that we are using the <a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/proto3\">proto3<\/a> version of the protocol buffer\u2019s language. Using <code>import<\/code>, we import message definitions defined in a separate file. gRPC or protocol buffers does not require us to do this, and it is a purely personal preference to keep the service definitions and the message types separate.<\/p>\n<p>The <code>CreateUser<\/code> function accepts a request of type <code>CreateUserRequest<\/code> defined in the <code>users<\/code> package and returns a result of type <code>CreateUserResult<\/code> defined in the same package. This function simulates the user-signup functionality of our <code>Users<\/code> service.<\/p>\n<p>The <code>GetUsers<\/code> function accepts a request of type <code>GetUsersRequest<\/code> and returns a <strong>stream<\/strong> of <code>GetUsersResult<\/code> objects. Specifying the output as a stream allows us to return part of the complete response to the client as soon as they are ready. This function simulates the functionality of returning the user details of a given user or multiple users.<\/p>\n<p>The <code>user_types.proto<\/code> file imported above defines the messages. You can see the entire file in the <code>demo1\/grpc-services\/protos\/users\/<\/code> subdirectory. It starts off by defining <code>proto3<\/code> syntax as above. However, it also defines a <code>package<\/code>:<\/p>\n<pre class=\"brush:py\">syntax = \"proto3\"; \r\npackage users;<\/pre>\n<p>Defining a new package allows us to define a namespace and hence we don\u2019t have to worry about not using the same message names across different services.<\/p>\n<p>Next, we define the message <code>User<\/code> describing a user in our service:<\/p>\n<pre class=\"brush:py\">message User { \r\n  string username = 1; \r\n  uint32 user_id = 2; \r\n}<\/pre>\n<p>We then define the message we\u2019ll use to return the result of a create-user operation:<\/p>\n<pre class=\"brush:py\">message CreateUserResult { \r\n  User user = 1; \r\n}<\/pre>\n<p>Above, we define the <code>CreateUserResult<\/code> message to have a single field of type <code>User<\/code> (defined earlier). The <code>GetUsers<\/code> function allows querying multiple users at once. Hence we define the <code>GetUsesRequest<\/code> message as follows:<\/p>\n<pre class=\"brush:py\">message GetUsersRequest { \r\n  repeated User user = 1; \r\n}<\/pre>\n<p>When a field in a message is defined as <code>repeated<\/code>, the message can have this field zero or more times. In Python, it is equivalent to defining a list of users.<\/p>\n<p>Next, use the service and types definition to generate language-specific bindings that will allow us to implement servers to use the above service and clients to talk to the server. Before we can do that however, we will create Python 3.5 virtual environment, activate it, and install two packages, <a href=\"https:\/\/pypi.python.org\/pypi\/grpcio\/\">grpcio<\/a> and <a href=\"https:\/\/pypi.python.org\/pypi\/grpcio-tools\">grpcio-tools<\/a>:<\/p>\n<pre class=\"brush:py\">$ python3.5 -m venv ~\/.virtualenvs\/grpc \r\n$ . ~\/.virtualenvs\/grpc\/activate \r\n$ python -m pip install grpcio grpcio-tools<\/pre>\n<h2>Writing the Server<\/h2>\n<p>Let\u2019s generate the Python bindings from the above protobuf definition:<\/p>\n<pre class=\"brush:py\">$ cd demo1\/grpc-services\/protos\/ \r\n$ .\/build.sh<\/pre>\n<p>The <code>build.sh<\/code> is a bash script that wraps around the <code>grpc-tools<\/code> package and essentially does the following:<\/p>\n<pre class=\"brush:py\">$ cd users \r\n$ mkdir ..\/gen-py \r\n$ python -m grpc_tools.protoc \r\n    \\ --proto_path=.\r\n    \\ --python_out=..\/gen-py \r\n    \\ --grpc_python_out=..\/gen-py \r\n    \\ *.proto<\/pre>\n<p>The arguments serve different purposes:<\/p>\n<ul>\n<li><code>proto_path<\/code>: Path to look for the protobuf definitions<\/li>\n<li><code>python_out<\/code>: Directory to generate the protobuf Python code<\/li>\n<li><code>grpc_python_out<\/code>: Directory to generate the gRPC Python code<\/li>\n<\/ul>\n<p>The last argument specifies the protobuf files to compile.<\/p>\n<p>The created <code>gen-py<\/code> directory will have the following four generated files:<\/p>\n<p><code>- users_types_pb2.py<br \/>\n- users_types_pb2_grpc.py<br \/>\n- users_pb2.py<br \/>\n- users_pb2_grpc.py<\/code><\/p>\n<p>The <code>*_pb2.py<\/code> files has the code corresponding to the types we have defined and the <code>*_grpc.py<\/code> files has the generated code related to the functions we have defined.<\/p>\n<p>Using the above generated code, we will write our \u201cservicer\u201d code:<\/p>\n<pre class=\"brush:py\">import users_pb2_grpc as users_service \r\nimport users_types_pb2 as users_messages\r\n\r\nclass UsersService(users_service.UsersServicer):\r\n\r\n    def CreateUser(self, request, context):\r\n        metadata = dict(context.invocation_metadata())\r\n        print(metadata)\r\n        user = users_messages.User(username=request.username, user_id=1)\r\n        return users_messages.CreateUserResult(user=user)\r\n\r\n    def GetUsers(self, request, context):\r\n        for user in request.user:\r\n            user = users_messages.User(\r\n                username=user.username, user_id=user.user_id\r\n            )\r\n            yield users_messages.GetUsersResult(user=user)<\/pre>\n<p>The <code>UsersService<\/code> subclasses the <code>UsersServicer<\/code> class generated in <code>users_pb2_grpc<\/code> and implements the two functions implemented by our service <code>CreateUser<\/code> and <code>GetUsers<\/code>. Each function accepts two arguments: <code>request<\/code> referring to the incoming request message and <code>context<\/code> giving access to various contextual data.<\/p>\n<p>In the <code>CreateUser<\/code> function, we see an example of accessing the metadata associated with the request. <code>metadata<\/code> is a list of arbitrary key-value pairs that the client can send along with a request and is part of the <a href=\"https:\/\/grpc.io\/docs\/guides\/concepts.html#metadata\">gRPC<\/a> specification itself. We access it by calling the <code>invocation_metadata()<\/code> method of the <code>context<\/code> object.<\/p>\n<p>The reason we need the explicit <code>dict<\/code> conversion is because they are <a href=\"https:\/\/github.com\/grpc\/grpc\/issues\/12301\">returned<\/a> as a list of tuples. Since the <code>CreateUser<\/code> function merely simulates a user-signup functionality, we just return back a new <code>User<\/code> object, with the <code>username<\/code> being the same as that provided in the request (a <code>CreateUser<\/code> object) accessible via <code>request.username<\/code> and set the <code>user_id<\/code> as 1. However, we do not send the newly created <code>user<\/code> object on its own but wrap it in a <code>CreateUserResult<\/code> object.<\/p>\n<p>The <code>GetUsers<\/code> function simulates the funcionality of querying user details. Recall that our <code>GetUsersRequest<\/code> object declares the <code>user<\/code> field as repeated. Hence, we iterate over the user field, with each item being an <code>User<\/code> object. We access the <code>username<\/code> and <code>user_id<\/code> from the object and use those to create a new <code>User<\/code> object.<\/p>\n<p>The output of the <code>GetUsers<\/code> function was declared to be a stream of <code>GetUsersResult<\/code> messages. Hence, we wrap the created <code>User<\/code> object in a <code>GetUsersResult<\/code> and <code>yield<\/code> it back to the client.<\/p>\n<p>The next step is to set up our server code to be able to process incoming gRPC requests and hand it over to our <code>UsersService<\/code> class:<\/p>\n<pre class=\"brush:py\">def serve():\r\n    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))\r\n    users_service.add_UsersServicer_to_server(UsersService(), server)\r\n    server.add_insecure_port('127.0.0.1:50051')\r\n    server.start()\r\n    try:\r\n        while True:\r\n            time.sleep(_ONE_DAY_IN_SECONDS)\r\n    except KeyboardInterrupt:\r\n        server.stop(0)<\/pre>\n<p>The <a href=\"https:\/\/grpc.io\/grpc\/python\/grpc.html?highlight=context#grpc.server\">grpc.Server<\/a> function creates a server. We call it above with the only required argument, a <code>futures.ThreadPoolExecutor<\/code> with the maximum number of workers set to 10. Then we call the <code>add_UsersServicer_to_server<\/code> function to register <code>UsersService<\/code> with the server.<\/p>\n<p>Using <code>add_insecure_port<\/code>, we set up the listening IP address and port and then start the server using the <code>start()<\/code> method. The <code>add_insecure_port<\/code> function is used since we are not setting SSL\/TLS for our client\/server communication and authentication.<\/p>\n<p>The code for the server can be found in <code>demo1\/grpc-services\/users\/server\/server.py<\/code>.<\/p>\n<p>Let\u2019s now start our server:<\/p>\n<pre class=\"brush:py\">$ cd demo1\/grpc-services\/users\/\r\n$ .\/run-server.sh<\/pre>\n<p>The <code>run-server.sh<\/code> bash script is basically:<\/p>\n<pre class=\"brush:py\">$ PYTHONPATH=..\/..\/protos\/gen-py\/ python server.py<\/pre>\n<p>!Sign up for a free Codeship Account<\/p>\n<h2>Writing a Client<\/h2>\n<p>To interact with our above server, a gRPC client will first create a <code>channel<\/code> to our server and create a <code>stub<\/code> object to interact with the users service via this channel:<\/p>\n<pre class=\"brush:py\">channel = grpc.insecure_channel('localhost:50051')\r\ntry:\r\n    grpc.channel_ready_future(channel).result(timeout=10)\r\nexcept grpc.FutureTimeoutError:\r\n    sys.exit('Error connecting to server')\r\nelse:\r\n    stub = users_service.UsersStub(channel)<\/pre>\n<p>The <code>channel_ready_future<\/code> function allows the client to wait for a specified timeout duration (in seconds) for the server to be ready. If our client times out, we exit; else, we create a <code>UsersStub<\/code> object passing the channel created as an argument.<\/p>\n<p>Using this stub object, we invoke a gRPC call as follows:<\/p>\n<pre class=\"brush:py\">metadata = [('ip', '127.0.0.1')]\r\nresponse = stub.CreateUser(\r\n    users_messages.CreateUserRequest(username='tom'),\r\n    metadata=metadata,\r\n)\r\nif response:\r\n    print(\"User created:\", response.user.username)<\/pre>\n<p>Above, we see a demonstration of how we pass additional metadata as part of a request. In a realistic scenario, we will pass in data such as a request ID, the authenticated user ID making the request, etc.<\/p>\n<p>Next, we see how we create a message that has a field repeated twice:<\/p>\n<pre class=\"brush:py\">request = users_messages.GetUsersRequest(\r\n    user=[users_messages.User(username=\"alexa\", user_id=1),\r\n          users_messages.User(username=\"christie\", user_id=1)]\r\n)<\/pre>\n<p>Since the <code>GetUsersRequest<\/code> message specified the field <code>user<\/code> as repeated, we create a list of <code>User<\/code> objects and set it as the value of this field.<\/p>\n<p>The result of the <code>GetUsers<\/code> function is a stream. Hence, we use the following construct to access the responses:<\/p>\n<pre class=\"brush:py\">response = users_service.GetUsers(request)\r\nfor resp in response:\r\n    print(resp)<\/pre>\n<p>Let\u2019s now run the client in the <code>demo1\/grpc-services\/users\/sample_client_demo.py<\/code> file:<\/p>\n<pre class=\"brush:py\">$ cd demo1\/grpc-services\/users \r\n$ PYTHONPATH=..\/protos\/gen-py\/ python sample_client_demo.py \r\nUser created: tom\r\nuser {\r\n  username: \"alexa\"\r\n  user_id: 1\r\n}\r\n\r\nuser {\r\n  username: \"christie\"\r\n  user_id: 1\r\n}<\/pre>\n<p>On the server side, we will see the metadata being printed for the incoming client request:<\/p>\n<pre class=\"brush:py\">{'ip': '127.0.0.1', 'user-agent': 'grpc-python\/1.6.0 grpc-c\/4.0.0 (manylinux; chttp2; garcia)'}<\/pre>\n<h2>Setting Client-side Timeout<\/h2>\n<p>When making a request, we can set client-side timeouts so that our client doesn\u2019t get into a state where it\u2019s waiting for a long time for a request to complete. There\u2019s no way currently to set a stub-wide timeout; therefore, we have to specify the timeout per call, like so:<\/p>\n<pre class=\"brush:py\">response = stub.GetUsers(request, timeout=30)<\/pre>\n<p>Above, we set the timeout to 30 seconds. If the client doesn\u2019t get a response from the server within 30 seconds, it will raise a <code>grpc.RpcError<\/code> exception with the status code <code>DEADLINE_EXCEEDED<\/code>. Ideally, we will catch the exception and report a user-friendly error message.<\/p>\n<h2>Demo Web Application Talking to gRPC<\/h2>\n<p>The <code>demo1\/webapp<\/code> directory contains a Flask application exporting a single endpoint <code>\/users\/<\/code> that invokes the <code>GetUsers<\/code> gRPC function and streams the responses back:<\/p>\n<pre class=\"brush:py\">@app.route('\/users\/')\r\ndef users_get():\r\n    request = users_messages.GetUsersRequest(\r\n        user=[users_messages.User(username=\"alexa\", user_id=1),\r\n              users_messages.User(username=\"christie\", user_id=1)]\r\n    )\r\n    def get_user():\r\n        response = app.config['users'].GetUsers(request)\r\n        for resp in response:\r\n            yield MessageToJson(resp)\r\n    return Response(get_user(), content_type='application\/json')<\/pre>\n<p>Since the response from our gRPC function is a stream, we create a generator function <code>get_user()<\/code> to yield a response as we get one. We use the <code>MessageToJson<\/code> function from the <code>protobuf<\/code> Python package to convert a protobuf message to a JSON object.<\/p>\n<h2>What\u2019s Next?<\/h2>\n<p>In the next article, we will be enhancing our gRPC server and learning about:<\/p>\n<ul>\n<li>Writing a secure gRPC server<\/li>\n<li>Error handling<\/li>\n<li>Writing interceptors and exporting metrics<\/li>\n<\/ul>\n<p>The code listings for this article can be found in <code>demo1<\/code> sub-directory in this <a href=\"https:\/\/github.com\/amitsaha\/python-grpc-demo\">git repo<\/a>.<\/p>\n<h2>Resources<\/h2>\n<ul>\n<li><a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/proto\">proto3<\/a><\/li>\n<li><a href=\"https:\/\/grpc.io\/docs\/quickstart\/python.html\">gRPC + Python Quickstart<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/reference\/python-generated\">Python generated code reference<\/a><\/li>\n<li><a href=\"https:\/\/grpc.io\/docs\/guides\/concepts.html\">gRPC concepts<\/a><\/li>\n<li><a href=\"https:\/\/grpc.io\/docs\/guides\/wire.html\">gRPC wire format<\/a><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Web Code Geeks with permission by Amit Saha, partner at our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\" target=\"_blank\" rel=\"noopener\">WCG program<\/a>. See the original article here: <a href=\"https:\/\/blog.codeship.com\/using-grpc-in-python\/\" target=\"_blank\" rel=\"noopener\">Using gRPC in Python<\/a><\/p>\n<p>Opinions expressed by Web Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is an alternative to other language-neutral RPC frameworks such as Apache Thrift and Apache Arvo. In the first part of this series on using gRPC in Python, we will implement a gRPC service in &hellip;<\/p>\n","protected":false},"author":1138,"featured_media":1651,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53],"tags":[],"class_list":["post-18750","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using gRPC in Python - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using gRPC in Python - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-09-26T09:15:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Amit Saha\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Amit Saha\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\"},\"author\":{\"name\":\"Amit Saha\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/4be953a89cfde2033d2d0ccb8352a39e\"},\"headline\":\"Using gRPC in Python\",\"datePublished\":\"2017-09-26T09:15:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\"},\"wordCount\":1455,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"articleSection\":[\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\",\"name\":\"Using gRPC in Python - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"datePublished\":\"2017-09-26T09:15:15+00:00\",\"description\":\"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/python\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Using gRPC in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/4be953a89cfde2033d2d0ccb8352a39e\",\"name\":\"Amit Saha\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9970b1486d07f680cee5d46882be11a25b90a35fd6dae0b43c589a71b885edea?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9970b1486d07f680cee5d46882be11a25b90a35fd6dae0b43c589a71b885edea?s=96&d=mm&r=g\",\"caption\":\"Amit Saha\"},\"description\":\"Amit Saha is a software engineer and author of Doing Math with Python. He's written for Linux Journal, Linux Voice, and Linux Magazine.\",\"sameAs\":[\"https:\/\/blog.codeship.com\/\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/amit-saha\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using gRPC in Python - Web Code Geeks - 2026","description":"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/","og_locale":"en_US","og_type":"article","og_title":"Using gRPC in Python - Web Code Geeks - 2026","og_description":"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is","og_url":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-09-26T09:15:15+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","type":"image\/jpeg"}],"author":"Amit Saha","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Amit Saha","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/"},"author":{"name":"Amit Saha","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/4be953a89cfde2033d2d0ccb8352a39e"},"headline":"Using gRPC in Python","datePublished":"2017-09-26T09:15:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/"},"wordCount":1455,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","articleSection":["Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/","url":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/","name":"Using gRPC in Python - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","datePublished":"2017-09-26T09:15:15+00:00","description":"gRPC is an HTTP\/2-based Remote Procedure Call (RPC) framework that uses protocol buffers (protobuf) as the underlying data serialization framework. It is","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/python\/using-grpc-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Python","item":"https:\/\/www.webcodegeeks.com\/category\/python\/"},{"@type":"ListItem","position":3,"name":"Using gRPC in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/4be953a89cfde2033d2d0ccb8352a39e","name":"Amit Saha","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9970b1486d07f680cee5d46882be11a25b90a35fd6dae0b43c589a71b885edea?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9970b1486d07f680cee5d46882be11a25b90a35fd6dae0b43c589a71b885edea?s=96&d=mm&r=g","caption":"Amit Saha"},"description":"Amit Saha is a software engineer and author of Doing Math with Python. He's written for Linux Journal, Linux Voice, and Linux Magazine.","sameAs":["https:\/\/blog.codeship.com\/"],"url":"https:\/\/www.webcodegeeks.com\/author\/amit-saha\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18750","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/1138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=18750"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18750\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/1651"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=18750"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=18750"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=18750"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}