Appendix B: Creating a gRPC Server in Python
One of the very cool things about gRPC is that it has excellent cross-platform support, so you can use different languages and platforms to create the different components of your distributed application.
Here’s how to build a simple gRPC pricing server using Python that will communicate with the Autobarn.PricingClient
we created during the workshop.
You’ll need Python for these examples. To check whether you’ve got it installed, type
python --version
at a console prompt. If you get
Python 3.10.0
(or anything starting with Python 3), you’re good to go. If not, you’ll need to install Python first.
Create a python
directory in the Autobarn
project directory:
D:\autobarn> mkdir python
D:\autobarn> cd python
Install the grpcio-tools
:
D:\autobarn\python> python -m pip install grpcio-tools
Copy the price.proto
file from the Autobarn.PricingServer
project.
Run the Python grpc_tools.protoc
compiler:
python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. --proto_path . price.proto
python -m grpc_tools.protoc
runs the protocol buffers compiler that’s bundled withgrpcio-tools
-I .
specifies the directory where any files imported by our.proto
file can be found. (We don’t have any, but we still have to specify this, because computers are stupid.)--python_out=. --grpc_python_out=.
specifies the output folders where the generated Python code will go--proto_path .
specifies the folder to search for.proto
files.price.proto
is the name of our protocol spec file.
Now you need to implement the pricing service, and add the grpc endpoints. You’ll end up with something like this:
import grpc
from concurrent import futures
import time
import os
import price_pb2_grpc as pb2_grpc
import price_pb2 as pb2
class PricingService(pb2_grpc.PricerServicer):
def __init__(self, *args, **kwargs):
pass
def GetPrice(self, request, context):
print(request)
if "ford" in request.modelCode.lower():
result = {'price': 5000, 'currencyCode': 'EUR'}
elif "brown" in request.color.lower():
result = {'price': 1250, 'currencyCode': 'SEK'}
elif "delorean" in request.modelCode.lower():
result = {'price': 50000, 'currencyCode': 'USD'}
else:
price = 1000 + (request.year * 10)
result = {'price': price, 'currencyCode': 'GBP '}
return pb2.PriceReply(**result)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
pb2_grpc.add_PricerServicer_to_server(PricingService(), server)
server.add_insecure_port('[::]:5002')
# If you've created a localhost HTTPS certificate, uncomment these lines to use it.
# key = open('localhost.key', 'rb').read()
# crt = open('localhost.crt', 'rb').read()
# server_credentials = grpc.ssl_server_credentials(((key, crt,),))
# server.add_secure_port('[::]:5003', server_credentials)
server.start()
print("Autobarn gRPC Pricing Server running.")
server.wait_for_termination()
if __name__ == '__main__':
serve()
This example can be used with an HTTPS certificate created by following the instructions in appendix A.
Run your server with:
python pricing_server.py
(Remember you can’t run two services on port 5003 at the same time, so if you’re still running the .NET Autobarn.PricingServer
it’ll crash.)