Python Flask grpc gateway

PreRequirements

requirements.txt

1
2
3
4
5
6
7
celery==4.2.1
grpcio==1.19.0
grpcio-tools==1.19.0
ontology-python-sdk==1.3.1
protobuf==3.7.0
Flask==1.0.2
gunicorn==19.9.0

Install Dependent Packages

1
2
pyenv activate env_flask_grpc
pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

proto/demo.proto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
syntax = "proto3";

package demo;

message RequestData {
string data = 1;
}

message ResponseData {
int64 return_code = 1;
string message = 2;
string data = 3;
}

service DemoService {

rpc CreateOne(RequestData) returns (ResponseData) {}
rpc DeleteOne(RequestData) returns (ResponseData) {}
rpc TransferOne(RequestData) returns (ResponseData) {}
rpc GetCreateNotify(RequestData) returns (ResponseData) {}

}

build.sh

1
2
3
4
python -m grpc_tools.protoc -I/usr/local/include -I. \
--grpc_python_out=. \
--python_out=. \
-I./proto/ demo.proto

demo_flask.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask
app = Flask(__name__)

import grpc

import demo_pb2
import demo_pb2_grpc


@app.route('/grpc')
def hello_world_grpc():
with grpc.insecure_channel('127.0.0.1:9090') as channel:
client = demo_pb2_grpc.DemoServiceStub(channel)

response = client.CreateOne(demo_pb2.RequestData(
data="call create one from client",
))
print(response.return_code, response.message, response.data)
return 'Hello, World grpc!'


@app.route('/')
def hello_world():
return 'Hello, World!'



run.sh

1
2
export FLASK_APP=demo_flask.py
gunicorn -w 4 -b 127.0.0.1:4000 demo_flask:app

Run Server

1
./run.sh

Python Flask 范例

PreRequirements

requirements.txt

1
2
Flask==1.0.2
gunicorn==19.9.0

Install Dependent Packages

1
2
pyenv activate env_grpc_demo
pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

demo_flask.py

1
2
3
4
5
6
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

run.sh

1
2
export FLASK_APP=demo_flask.py
gunicorn -w 4 -b 127.0.0.1:4000 demo_flask:app

Run Server

1
./run.sh

Python grpc 构建微服务

PreRequirements

requirements.txt

1
2
3
4
5
celery==4.2.1
grpcio==1.19.0
grpcio-tools==1.19.0
ontology-python-sdk==1.3.1
protobuf==3.7.0

Install Dependent Packages

1
2
pyenv activate env_grpc_demo
pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

proto/demo.proto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
syntax = "proto3";

package demo;

message RequestData {
string data = 1;
}

message ResponseData {
int64 return_code = 1;
string message = 2;
string data = 3;
}

service DemoService {

rpc CreateOne(RequestData) returns (ResponseData) {}
rpc DeleteOne(RequestData) returns (ResponseData) {}
rpc TransferOne(RequestData) returns (ResponseData) {}
rpc GetCreateNotify(RequestData) returns (ResponseData) {}

}

build.sh

1
2
3
4
python -m grpc_tools.protoc -I/usr/local/include -I. \
--grpc_python_out=. \
--python_out=. \
-I./proto/ demo.proto

Gen demo.proto to python grpc code

1
./build.sh

server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import logging
import time
from concurrent import futures

import grpc

import demo_pb2
import demo_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class DemoService(demo_pb2_grpc.DemoServiceServicer):

def __init__(self):
pass

def CreateOne(self, request, context):

print("C_2_S CreateOne: >>>>> ", request)

response = demo_pb2.ResponseData(
return_code=0,
message="success",
data=""
)

print("S_2_C CreateOne: <<<<< ", response)

return response

def DeleteOne(self, request, context):

print("C_2_S DeleteOne: >>>>> ", request)

response = demo_pb2.ResponseData(
return_code=0,
message="success",
data=""
)

print("S_2_C DeleteOne: <<<<< ", response)

return response

def TransferOne(self, request, context):

print("C_2_S TransferOne: >>>>> ", request)

response = demo_pb2.ResponseData(
return_code=0,
message="success",
data=""
)

print("S_2_C TransferOne: <<<<< ", response)

return response

def GetCreateNotify(self, request, context):

print("C_2_S GetCreateNotify: >>>>> ", request)

response = demo_pb2.ResponseData(
return_code=0,
message="success",
data=""
)

print("S_2_C GetCreateNotify: <<<<< ", response)

return response


def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
demo_pb2_grpc.add_DemoServiceServicer_to_server(DemoService(), server)
server.add_insecure_port('[::]:9090')
server.start()

print("listen: 9090")

try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)


if __name__ == '__main__':
logging.basicConfig()
serve()

Run Server

1
python server.py

client.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import logging

import grpc

import demo_pb2
import demo_pb2_grpc


def run():
with grpc.insecure_channel('127.0.0.1:9090') as channel:
client = demo_pb2_grpc.DemoServiceStub(channel)

response = client.CreateOne(demo_pb2.RequestData(
data="call create one from client",
))
print(response.return_code, response.message, response.data)


response = client.DeleteOne(demo_pb2.RequestData(
data="call delete one from client",
))
print(response.return_code, response.message, response.data)

response = client.TransferOne(demo_pb2.RequestData(
data="call get transfer one from client",
))
print(response.return_code, response.message, response.data)

response = client.GetCreateNotify(demo_pb2.RequestData(
data="call create one from client",
))
print(response.return_code, response.message, response.data)


if __name__ == '__main__':
logging.basicConfig()
run()

Run Client

1
python client.py

Centos 7.4 mysql 5.7 环境搭建

Mysql 5.7 Server and Client

1
2
3
4
5
wget http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
yum localinstall mysql57-community-release-el7-7.noarch.rpm
yum repolist enabled | grep "mysql.*-community.*"
yum install -y mysql-community-server
yum install -y mysql-community-client

Ubuntu Golang 开发环境搭建

go_src

Setup Development Environment

Ubuntu Installation

1
2
3
4
sudo add-apt-repository ppa:gophers/archive
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install build-essential autoconf libtool libsysfs-dev

Download & Install Golang 1.11.5

1
2
3
wget https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz
sudo tar -xvf go1.12.4.linux-amd64.tar.gz
sudo mv go /usr/local

FIXME: vi ~/.bashrc not useful ???

1
2
3
4
export GOROOT=/usr/local/go
export GOPATH=$HOME/workspace
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
export GOPROXY=https://goproxy.io

Build Protobuf from source

1
2
3
4
5
6
7
8
9
git clone https://github.com/google/protobuf.git
cd protobuf/
git clone https://github.com/google/googlemock.git
mv googlemock gmock
./autogen.sh
./configure
make
sudo make install
export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/usr/local/lib64:/usr/lib64

Install proto-gen-go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GIT_TAG="v1.2.0" # change as needed
go get -d -u github.com/golang/protobuf/protoc-gen-go
git -C "$(go env GOPATH)"/src/github.com/golang/protobuf checkout $GIT_TAG
go install github.com/golang/protobuf/protoc-gen-go
# micro
go get -u github.com/micro/protobuf/protoc
go get -u github.com/micro/protobuf/protoc-gen-go
go install github.com/micro/protobuf/protoc-gen-go
# protoc-gen-micro
go get github.com/micro/protoc-gen-micro
# grpc
go get -v -u github.com/grpc-ecosystem/grpc-gateway
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go install github.com/golang/protobuf/protoc-gen-go

SQL

1
2
3
4
DROP DATABASE txin_user;
CREATE DATABASE txin_user
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;

Centos 7.4 Docker 安装

阿里云镜像安装 Docker

1
2
3
4
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y update
yum install docker-ce

启动docker 服务

1
2
systemctl start docker
systemctl enable docker

安装 docker-compose

1
2
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

python pyenv 开发环境搭建

Centos 7.4

yum

1
2
yum -y groupinstall "Development Tools"
yum -y install zlib-devel readline-devel sqlite-devel bzip2-devel openssl-devel libffi-devel mysql-devel

pyenv

1
2
3
4
5
6
7
8
9
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile

exec "$SHELL"

pyenv install 3.5.5

pyenv-virtualenv

1
2
3
4
5
6
7
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile

exec "$SHELL"

pyenv virtualenv 3.5.5 env_355

pyenv activate

1
2
pyenv activate env_355
pyenv deactivate