Communicate between Elixir and Python with gRPC

1.First of all

Try cross-language communication between Elixir and Python using gRPC.

In this article,

--gRPC server: Elixir --gRPC client: Python3

It is said.

Execution environment

hard Raspberry Pi 3B+
OS Raspbian Buster, Ubuntu Server 20.04LTS
Python 3.7.3
Elixir 1.7.4 (compiled with Erlang/OTP 21)

2. Elixir side

First, prepare for the Elixir side.

Here, the sample "[examples / helloworld](https://github.com/elixir-grpc/" included in elixir-grpc library grpc / tree / master / examples / helloworld) ”.

When the client requests by assigning a name to name, the server returns the string "Hello ".

Command line


$ pwd
..../elixir/
#Clone
$ git clone https://github.com/elixir-grpc/grpc.git
#Go to the sample directory
$ cd ./grpc/examples/helloworld/
#Dependency handling, compiling.
$ mix do deps.get, compile

2. Python side

The following is the procedure for creating a client / server on the Python side.

(1) Installation of grpc tool

$ sudo apt install python3-grpcio python3-grpc-tools -y

(2) Interface generation

Prepare a tool to parse the proto file and generate an interface for Python.

Command line


$ pwd
..../elixir/grpc/examples/helloworld
#Create a folder to save Python scripts
$ mkdir python
$ cd python
#Copy the proto file defined by elixir
python $ cp ../priv/protos/helloworld.proto ./
#Generate tool file
python $ touch codegen.py
python $ chmod 755 codegen.py

Source code for tools that generate interfaces for Python. This time, we are targeting helloworld.proto, so we use__NAME = "helloworld"in the code.

codegen.py


#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
"""
Compile proto files

The following two files will be generated.
・*_pb2.py      :Serialization interface
・*_pb2_grpc.py :gRPC interface
"""
from grpc.tools import protoc

#File name of proto (name part)
__NAME="helloworld"

#Generate an interface for Python
protoc.main(
    (
        '',
        '-I.',
        '--python_out=.',
        '--grpc_python_out=.',
        ('{}.proto'.format(__NAME)),
    )
)

Generates an interface for Python.

Command line


python $ ./codegen.py
python $ ls
codegen.py  helloworld_pb2_grpc.py  helloworld_pb2.py  helloworld.proto

Two files, * _pb2.py and * _ pb2_grpc.py, have been generated.

(3) Creating a client on the Python side

Create client script

Command line


#Generate file
python $ touch client.py
python $ chmod 755 client.py

client.py


#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
"""
gRPC client
by myasu 2020 
"""

import sys
import grpc
#Import the interface generated from proto earlier
import helloworld_pb2
import helloworld_pb2_grpc


def grpc_client(request):
    """gRPC client communication processing
    Parameters
    ----------
    request : string
Messages to send to gRPC server
    """
    #Connect by specifying the address and port of the gRPC server on the Elixir side
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        #Request to the gRPC server on the Elixir side
        response = stub.SayHello(helloworld_pb2.HelloRequest(name=request))

    #Check the contents of response
    print(' Response:', response.message)


if __name__ == '__main__':
    """Main processing
    """
    #Reading arguments
    args = sys.argv
    #Check the length of the argument
    if len(args) == 2:
        #Run
        grpc_client(args[1])
    else:
        #error
        print('Arguments are too short')

Communication test between Python → Elixir → Python

First, start the server / Elixir side.

Terminal 1 / Elixir gRPC server side


$ mix grpc.server
10:58:01.872 [warn]  cowlib should be >= 2.9.0, it's 2.8.1 now. See grpc's README for details
10:58:01.977 [info]  Running Helloworld.Endpoint with Cowboy using http://0.0.0.0:50051

(... From here onward, it will be displayed when there is a client request ...)
22:58:04.739 [info]  Handled by Helloworld.Greeter.Server.say_hello
22:58:04.744 [info]  Response :ok in 4ms
22:58:09.237 [info]  Handled by Helloworld.Greeter.Server.say_hello
22:58:09.237 [info]  Response :ok in 15μs
22:58:13.552 [info]  Handled by Helloworld.Greeter.Server.say_hello
22:58:13.552 [info]  Response :ok in 15μs
[Ctrl-\]Stop at

Next, execute the client / Python side. Any message can be specified as an argument of the script.

Terminal 2-Python gRPC client side


python $ ./client.py chika
 Response: Hello chika
python $ ./client.py you
 Response: Hello you
python $ ./client.py ruby
 Response: Hello ruby
python $ ./client.py CYaRon!
 Response: Hello CYaRon!

The server will return the message with "Hello" at the beginning. With this feeling, communication between different languages was possible.

4. Reference materials

Recommended Posts

Communicate between Elixir and Python with gRPC
Communicate with FX-5204PS with Python and PyUSB
GRPC starting with Python
Programming with Python and Tkinter
Encryption and decryption with Python
Python and hardware-Using RS232C with Python-
python with pyenv and venv
I tried gRPC with Python
Works with Python and R
Difference between Ruby and Python split
Shining life with Python and OpenCV
Difference between java and python (memo)
Robot running with Arduino and python
Install Python 2.7.9 and Python 3.4.x with pip.
Difference between list () and [] in Python
Neural network with OpenCV 3 and Python 3
AM modulation and demodulation with python
Difference between == and is in python
[Python] font family and font with matplotlib
Scraping with Node, Ruby and Python
Authentication process with gRPC and Firebase Authentication
Scraping with Python, Selenium and Chromedriver
Scraping with Python and Beautiful Soup
Cooperation between python module and API
JSON encoding and decoding with python
Differences between Python, stftime and strptime
Hadoop introduction and MapReduce with Python
[GUI with Python] PyQt5-Drag and drop-
Difference between python2 series and python3 series dict.keys ()
Reading and writing NetCDF with Python
I played with PyQt5 and Python3
Reading and writing CSV with Python
Multiple integrals with Python and Sympy
[Python] Difference between function and method
Coexistence of Python2 and 3 with CircleCI (1.0)
Python --Difference between exec and eval
Easy modeling with Blender and Python
[Python] Difference between randrange () and randint ()
[Python] Difference between sorted and sorted (Colaboratory)
Sugoroku game and addition game with python
FM modulation and demodulation with Python
Data pipeline construction with Python and Luigi
Calculate and display standard weight with python
Differences in authenticity between Python and JavaScript
Monitor Mojo outages with Python and Skype
Differences between Ruby and Python in scope
FM modulation and demodulation with Python Part 3
[Automation] Manipulate mouse and keyboard with Python
difference between statements (statements) and expressions (expressions) in Python
Passwordless authentication with RDS and IAM (Python)
Python installation and package management with pip
Using Python and MeCab with Azure Databricks
Differences in syntax between Python and Java
Difference between PHP and Python finally and exit
POST variously with Python and receive with Flask
Capturing images with Pupil, python and OpenCV
Difference between @classmethod and @staticmethod in Python
Fractal to make and play with Python
A memo with Python2.7 and Python3 on CentOS
Let's try gRPC with Go and Docker
Use PIL and Pillow with Cygwin Python