From 1316f17a87434d88a3a52616697f2d908e0b3251 Mon Sep 17 00:00:00 2001 From: barriery Date: Tue, 18 Aug 2020 13:20:11 +0000 Subject: [PATCH] add grpc-gateway option into pipeline --- doc/COMPILE.md | 14 ++ doc/COMPILE_CN.md | 15 ++ doc/PIPELINE_SERVING.md | 162 +----------------- doc/PIPELINE_SERVING_CN.md | 162 +----------------- python/CMakeLists.txt | 8 +- .../pipeline/grpc-gateway/README_CN.md | 67 -------- .../pipeline/grpc-gateway/gateway/gen_code.sh | 13 -- .../pipeline/imdb_model_ensemble/README_CN.md | 24 +++ .../pipeline/imdb_model_ensemble/config.yml | 1 + python/examples/pipeline/ocr/config.yml | 1 + python/pipeline/gateway/__init__.py | 13 ++ .../gateway/proto}/gateway.proto | 0 .../gateway}/proxy_server.go | 15 +- python/pipeline/pipeline_server.py | 31 ++++ python/setup.py.app.in | 14 +- python/setup.py.client.in | 20 +-- python/setup.py.in | 9 +- python/setup.py.server.in | 16 +- python/setup.py.server_gpu.in | 29 ++-- python/util.py | 69 ++++++++ tools/serving_build.sh | 6 + 21 files changed, 218 insertions(+), 471 deletions(-) delete mode 100644 python/examples/pipeline/grpc-gateway/README_CN.md delete mode 100644 python/examples/pipeline/grpc-gateway/gateway/gen_code.sh create mode 100644 python/examples/pipeline/imdb_model_ensemble/README_CN.md create mode 100644 python/pipeline/gateway/__init__.py rename python/{examples/pipeline/grpc-gateway/gateway => pipeline/gateway/proto}/gateway.proto (100%) rename python/{examples/pipeline/grpc-gateway => pipeline/gateway}/proxy_server.go (84%) create mode 100644 python/util.py diff --git a/doc/COMPILE.md b/doc/COMPILE.md index 1836f4fe..c619e012 100644 --- a/doc/COMPILE.md +++ b/doc/COMPILE.md @@ -62,7 +62,21 @@ pip install -r python/requirements.txt If Python3 is used, replace `pip` with `pip3`. +## GOPATH Setting +The default GOPATH is `$HOME/go`, which you can set to other values. +```shell +export GOPATH=$HOME/go +export PATH=$PATH:$GOPATH/bin +``` + +## Get go packages + +```shell +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger +go get -u github.com/golang/protobuf/protoc-gen-go +``` ## Compile Server diff --git a/doc/COMPILE_CN.md b/doc/COMPILE_CN.md index 1235653e..9da21334 100644 --- a/doc/COMPILE_CN.md +++ b/doc/COMPILE_CN.md @@ -62,6 +62,21 @@ pip install -r python/requirements.txt 如果使用 Python3,请以 `pip3` 替换 `pip`。 +## GOPATH 设置 + +默认 GOPATH 设置为 `$HOME/go`,您也可以设置为其他值。 +```shell +export GOPATH=$HOME/go +export PATH=$PATH:$GOPATH/bin +``` + +## 获取 Go packages + +```shell +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway +go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger +go get -u github.com/golang/protobuf/protoc-gen-go +``` ## 编译Server部分 diff --git a/doc/PIPELINE_SERVING.md b/doc/PIPELINE_SERVING.md index 9d907705..04014ba2 100644 --- a/doc/PIPELINE_SERVING.md +++ b/doc/PIPELINE_SERVING.md @@ -254,6 +254,7 @@ Where `response_op` is the responseop mentioned above, PipelineServer will initi port: 18080 # gRPC port worker_num: 1 # gRPC thread pool size (the number of processes in the process version servicer). The default is 1 build_dag_each_worker: false # Whether to use process server or not. The default is false +grpc_gateway_port: 0 # HTTP service port. Do not start HTTP service when the value is less or equals 0. The default value is 0. dag: is_thread_op: true # Whether to use the thread version of OP. The default is true client_type: brpc # Use brpc or grpc client. The default is brpc @@ -420,164 +421,3 @@ Specific operation: open Chrome browser, input in the address bar `chrome://trac The profile function can be enabled by setting `profile=True` in the `predict` interface on the client side. After the function is enabled, the client will print the log information corresponding to the prediction to the standard output during the prediction process, and the subsequent analysis and processing are the same as that of the server. - - - -## How to start HTTP service with gRPC-gateway - -Based on [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway), PipelineServing can provide RESTful API. Refer to the [document](https://grpc-ecosystem.github.io/grpc-gateway/docs/background.html) of grpc-gateway. Relevant code reference `python/examples/pipeline/grpc-gateway`. - -### Installation - -#### 1. Protobuf 3 - -In the container we provided, you need to install `autoconf`, `automake`, `libtool`: - -```shell -yum install -y autoconf automake libtool -``` - -Compile protobuf 3: - -```shell -mkdir tmp -cd tmp -git clone https://github.com/google/protobuf -cd protobuf && git submodule update --init --recursive -./autogen.sh -./configure -make -make check -sudo make install -``` - -#### 2. Go packages - -Set `GOPATH`: - -```shell -export GOPATH=$HOME/go -export PATH=$PATH:$GOPATH/bin -``` - -Download packages: - -```shell -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger -go get -u github.com/golang/protobuf/protoc-gen-go -``` - -### Usage - -#### 1. Define proto file - -```protobuf -syntax = "proto3"; -package baidu.paddle_serving.pipeline_serving; -option go_package = ".;pipeline_gateway"; - -import "google/api/annotations.proto"; - -message Response { - repeated string key = 1; - repeated string value = 2; - int32 ecode = 3; - string error_info = 4; -}; - -message Request { - repeated string key = 1; - repeated string value = 2; -} - -service PipelineService { - rpc inference(Request) returns (Response) { - option (google.api.http) = { - post : "/pipeline/prediction" - body : "*" - }; - } -}; -``` - -#### 2. Generate gRPC stub and reverse-proxy - -```shell -# generate .pb.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --go_out=plugins=grpc:. \ - - -# generate .gw.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --grpc-gateway_out=logtostderr=true:. \ - -``` - -#### 3. Write an entry point of the proxy server - -```go -package main - -import ( - "flag" - "net/http" - "log" - - "github.com/golang/glog" - "golang.org/x/net/context" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "google.golang.org/grpc" - - gw "path/to/your_service_package" // TODO -) - -var ( - echoEndpoint = flag.String("echo_endpoint", "localhost:", "endpoint of YourService") // TODO -) - -func run() error { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - mux := runtime.NewServeMux() - opts := []grpc.DialOption{grpc.WithInsecure()} - err := gw.RegisterPipelineServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts) - if err != nil { - return err - } - - log.Println("start service") - return http.ListenAndServe(":8080", mux) // proxy port -} - -func main() { - flag.Parse() - defer glog.Flush() - - if err := run(); err != nil { - glog.Fatal(err) - } -} -``` - -#### 4. Compile the above go program and run - -```shell -go build .go -./ &>log.txt & -``` - -#### 5. Test RESTful API - -Take imdb model ensemble as an example: - -```shell -curl -X POST -k http://localhost:8080/pipeline/prediction -d '{"key": ["words"], "value": ["i am very sad | 0"]}' -``` diff --git a/doc/PIPELINE_SERVING_CN.md b/doc/PIPELINE_SERVING_CN.md index 571a55d8..5a6150b7 100644 --- a/doc/PIPELINE_SERVING_CN.md +++ b/doc/PIPELINE_SERVING_CN.md @@ -252,6 +252,7 @@ server.run_server() port: 18080 # gRPC端口号 worker_num: 1 # gRPC线程池大小(进程版 Servicer 中为进程数),默认为 1 build_dag_each_worker: false # 是否使用进程版 Servicer,默认为 false +grpc_gateway_port: 0 # HTTP 服务的端口号,若该值小于或等于 0 则不开启 HTTP 服务,默认为 0 dag: is_thread_op: true # 是否使用线程版Op,默认为 true client_type: brpc # 使用 brpc 或 grpc client,默认为 brpc @@ -417,164 +418,3 @@ if __name__ == "__main__": Client 端在 `predict` 接口设置 `profile=True`,即可开启 Profile 功能。 开启该功能后,Client 端在预测的过程中会将该次预测对应的日志信息打印到标准输出,后续分析处理同 Server。 - - - -## 如何通过 gRPC-gateway 开启 HTTP 服务 - -基于 [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway),PipelineServing 可以提供 RESTful API,参考 grpc-gateway 的[文档](https://grpc-ecosystem.github.io/grpc-gateway/docs/background.html),相关代码存放在`python/examples/pipeline/grpc-gateway`。 - -### 安装依赖 - -#### 1. Protobuf 3 - -在我们提供的容器中需要先安装 `autoconf` ,`automake`,`libtool` : - -```shell -yum install -y autoconf automake libtool -``` - -编译 protobuf 3: - -```shell -mkdir tmp -cd tmp -git clone https://github.com/google/protobuf -cd protobuf && git submodule update --init --recursive -./autogen.sh -./configure -make -make check -sudo make install -``` - -#### 2. Go packages - -设置 `GOPATH`: - -```shell -export GOPATH=$HOME/go -export PATH=$PATH:$GOPATH/bin -``` - -下载 packages: - -```shell -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger -go get -u github.com/golang/protobuf/protoc-gen-go -``` - -### 使用 gRPC-gateway - -#### 1. 定义 proto 文件 - -```protobuf -syntax = "proto3"; -package baidu.paddle_serving.pipeline_serving; -option go_package = ".;pipeline_gateway"; - -import "google/api/annotations.proto"; - -message Response { - repeated string key = 1; - repeated string value = 2; - int32 ecode = 3; - string error_info = 4; -}; - -message Request { - repeated string key = 1; - repeated string value = 2; -} - -service PipelineService { - rpc inference(Request) returns (Response) { - option (google.api.http) = { - post : "/pipeline/prediction" - body : "*" - }; - } -}; -``` - -#### 2. 生成 gRPC stub 和 反向代理 - -```shell -# generate .pb.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --go_out=plugins=grpc:. \ - - -# generate .gw.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --grpc-gateway_out=logtostderr=true:. \ - -``` - -#### 3. 编写代理服务器的入口程序 - -```go -package main - -import ( - "flag" - "net/http" - "log" - - "github.com/golang/glog" - "golang.org/x/net/context" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "google.golang.org/grpc" - - gw "path/to/your_service_package" // TODO -) - -var ( - echoEndpoint = flag.String("echo_endpoint", "localhost:", "endpoint of YourService") // TODO -) - -func run() error { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - mux := runtime.NewServeMux() - opts := []grpc.DialOption{grpc.WithInsecure()} - err := gw.RegisterPipelineServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts) - if err != nil { - return err - } - - log.Println("start service") - return http.ListenAndServe(":8080", mux) // proxy port -} - -func main() { - flag.Parse() - defer glog.Flush() - - if err := run(); err != nil { - glog.Fatal(err) - } -} -``` - -#### 4. 编译上述 Go 程序并运行 - -```shell -go build .go -./ &>log.txt & -``` - -#### 5. 测试 RESTful API - -以 imdb model ensemble 为例: - -```shell -curl -X POST -k http://localhost:8080/pipeline/prediction -d '{"key": ["words"], "value": ["i am very sad | 0"]}' -``` diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index edec4157..4d6b3ce3 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,7 +1,5 @@ if (CLIENT) file(INSTALL pipeline DESTINATION paddle_serving_client) - execute_process(COMMAND ${PYTHON_EXECUTABLE} run_codegen.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paddle_serving_client/pipeline/proto) file(GLOB_RECURSE SERVING_CLIENT_PY_FILES paddle_serving_client/*.py) set(PY_FILES ${SERVING_CLIENT_PY_FILES}) SET(PACKAGE_NAME "serving_client") @@ -11,13 +9,9 @@ endif() if (SERVER) if (NOT WITH_GPU) file(INSTALL pipeline DESTINATION paddle_serving_server) - execute_process(COMMAND ${PYTHON_EXECUTABLE} run_codegen.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paddle_serving_server/pipeline/proto) file(GLOB_RECURSE SERVING_SERVER_PY_FILES paddle_serving_server/*.py) else() file(INSTALL pipeline DESTINATION paddle_serving_server_gpu) - execute_process(COMMAND ${PYTHON_EXECUTABLE} run_codegen.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paddle_serving_server_gpu/pipeline/proto) file(GLOB_RECURSE SERVING_SERVER_PY_FILES paddle_serving_server_gpu/*.py) endif() set(PY_FILES ${SERVING_SERVER_PY_FILES}) @@ -25,6 +19,8 @@ if (SERVER) set(SETUP_LOG_FILE "setup.py.server.log") endif() +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/util.py + ${CMAKE_CURRENT_BINARY_DIR}/util.py) if (CLIENT) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.client.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py) diff --git a/python/examples/pipeline/grpc-gateway/README_CN.md b/python/examples/pipeline/grpc-gateway/README_CN.md deleted file mode 100644 index 257e0b3a..00000000 --- a/python/examples/pipeline/grpc-gateway/README_CN.md +++ /dev/null @@ -1,67 +0,0 @@ -# 通过 gRPC-gateway 开启 HTTP 服务 - -## 安装依赖 - -### 1. Protobuf 3 - -在我们提供的容器中需要先安装 `autoconf` ,`automake`,`libtool` : - -```shell -yum install -y autoconf automake libtool -``` - -编译 Protobuf 3: - -```shell -mkdir tmp -cd tmp -git clone https://github.com/google/protobuf -cd protobuf && git submodule update --init --recursive -./autogen.sh -./configure -make -make check -sudo make install -``` - -### 2. Go packages - -设置 `GOPATH`: -```shell -export GOPATH=$HOME/go -export PATH=$PATH:$GOPATH/bin -``` -下载 packages: -```shell -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway -go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger -go get -u github.com/golang/protobuf/protoc-gen-go -``` - -## 生成 gRPC stub 和 反向代理 - -```shell -cd gateway -sh gen_code.sh -``` - -## 编译 Go 程序 - -``` -go build proxy_server.go -``` - -## 运行测试 - -这里以 imdb model ensemble 为例: -```shell -cd ../imdb_model_ensemble/ -sh get_data.sh -python -m paddle_serving_server.serve --model imdb_cnn_model --port 9292 &> cnn.log & -python -m paddle_serving_server.serve --model imdb_bow_model --port 9393 &> bow.log & -python test_pipeline_server.py &> pipeline.log & -cd - -./proxy_server &> gateway.log & - -curl -X POST -k http://localhost:8080/pipeline/prediction -d '{"key": ["words"], "value": ["i am very sad | 0"]}' -``` diff --git a/python/examples/pipeline/grpc-gateway/gateway/gen_code.sh b/python/examples/pipeline/grpc-gateway/gateway/gen_code.sh deleted file mode 100644 index 9840f03a..00000000 --- a/python/examples/pipeline/grpc-gateway/gateway/gen_code.sh +++ /dev/null @@ -1,13 +0,0 @@ -# generate .pb.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --go_out=plugins=grpc:. \ - gateway.proto - -# generate .gw.go -protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --grpc-gateway_out=logtostderr=true:. \ - gateway.proto diff --git a/python/examples/pipeline/imdb_model_ensemble/README_CN.md b/python/examples/pipeline/imdb_model_ensemble/README_CN.md new file mode 100644 index 00000000..30b4425b --- /dev/null +++ b/python/examples/pipeline/imdb_model_ensemble/README_CN.md @@ -0,0 +1,24 @@ +# IMDB model ensemble 样例 + +## 获取模型 +``` +sh get_data.sh +``` + +## 启动服务 + +``` +python -m paddle_serving_server_gpu.serve --model imdb_cnn_model --port 9292 &> cnn.log & +python -m paddle_serving_server_gpu.serve --model imdb_bow_model --port 9393 &> bow.log & +python pipeline_server.py &>pipeline.log & +``` + +## 启动客户端 +``` +python pipeline_client.py +``` + +## HTTP 测试 +``` +curl -X POST -k http://localhost:9999/pipeline/prediction -d '{"key": ["words"], "value": ["i am very sad | 0"]}' +``` diff --git a/python/examples/pipeline/imdb_model_ensemble/config.yml b/python/examples/pipeline/imdb_model_ensemble/config.yml index 3f0b1bb8..fc637139 100644 --- a/python/examples/pipeline/imdb_model_ensemble/config.yml +++ b/python/examples/pipeline/imdb_model_ensemble/config.yml @@ -1,6 +1,7 @@ port: 18080 worker_num: 4 build_dag_each_worker: false +grpc_gateway_port: 9999 dag: is_thread_op: false client_type: brpc diff --git a/python/examples/pipeline/ocr/config.yml b/python/examples/pipeline/ocr/config.yml index 13a85d06..ed609bad 100644 --- a/python/examples/pipeline/ocr/config.yml +++ b/python/examples/pipeline/ocr/config.yml @@ -1,6 +1,7 @@ port: 18080 worker_num: 4 build_dag_each_worker: false +grpc_gateway_port: 9999 dag: is_thread_op: false client_type: brpc diff --git a/python/pipeline/gateway/__init__.py b/python/pipeline/gateway/__init__.py new file mode 100644 index 00000000..abf198b9 --- /dev/null +++ b/python/pipeline/gateway/__init__.py @@ -0,0 +1,13 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/python/examples/pipeline/grpc-gateway/gateway/gateway.proto b/python/pipeline/gateway/proto/gateway.proto similarity index 100% rename from python/examples/pipeline/grpc-gateway/gateway/gateway.proto rename to python/pipeline/gateway/proto/gateway.proto diff --git a/python/examples/pipeline/grpc-gateway/proxy_server.go b/python/pipeline/gateway/proxy_server.go similarity index 84% rename from python/examples/pipeline/grpc-gateway/proxy_server.go rename to python/pipeline/gateway/proxy_server.go index 6c483ef8..2b8abbe0 100644 --- a/python/examples/pipeline/grpc-gateway/proxy_server.go +++ b/python/pipeline/gateway/proxy_server.go @@ -15,23 +15,26 @@ package main import ( + "C" "flag" "net/http" "log" + "strconv" - "github.com/golang/glog" + //"github.com/golang/glog" "golang.org/x/net/context" "github.com/grpc-ecosystem/grpc-gateway/runtime" "google.golang.org/grpc" - gw "./gateway" + gw "./proto" ) var ( pipelineEndpoint = flag.String("pipeline_endpoint", "localhost:18080", "endpoint of PipelineService") ) -func run() error { +//export run_proxy_server +func run_proxy_server(port int) error { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -43,15 +46,17 @@ func run() error { return err } - log.Println("start service") - return http.ListenAndServe(":8080", mux) // proxy port + log.Println("start proxy service") + return http.ListenAndServe(":" + strconv.Itoa(port), mux) // proxy port } func main() { + /* flag.Parse() defer glog.Flush() if err := run(); err != nil { glog.Fatal(err) } + */ } diff --git a/python/pipeline/pipeline_server.py b/python/pipeline/pipeline_server.py index e8229e81..16cde089 100644 --- a/python/pipeline/pipeline_server.py +++ b/python/pipeline/pipeline_server.py @@ -61,6 +61,30 @@ class PipelineServer(object): self._port = None self._worker_num = None self._response_op = None + self._proxy_server = None + + def _grpc_gateway(self, port): + import os + from ctypes import cdll + from . import gateway + lib_path = os.path.join( + os.path.dirname(gateway.__file__), "libproxy_server.so") + proxy_server = cdll.LoadLibrary(lib_path) + proxy_server.run_proxy_server(port) + + def _run_grpc_gateway(self, port): + if port <= 0: + _LOGGER.info("Ignore grpc_gateway configuration.") + return + if not self._port_is_available(port): + raise SystemExit("Failed to run grpc-gateway: prot {} " + "is already used".format(port)) + if self._proxy_server is not None: + raise RuntimeError("Proxy server has been started.") + self._proxy_server = multiprocessing.Process( + target=self._grpc_gateway, args=(port, )) + self._proxy_server.daemon = True + self._proxy_server.start() def set_response_op(self, response_op): if not isinstance(response_op, ResponseOp): @@ -85,6 +109,7 @@ class PipelineServer(object): raise SystemExit("Failed to prepare_server: prot {} " "is already used".format(self._port)) self._worker_num = conf["worker_num"] + self._grpc_gateway_port = conf["grpc_gateway_port"] self._build_dag_each_worker = conf["build_dag_each_worker"] _LOGGER.info("============= PIPELINE SERVER =============") @@ -111,6 +136,8 @@ class PipelineServer(object): args=(bind_address, self._response_op, self._conf, i)) worker.start() workers.append(worker) + self._run_grpc_gateway( + self._grpc_gateway_port) # start grpc_gateway for worker in workers: worker.join() else: @@ -123,6 +150,8 @@ class PipelineServer(object): PipelineServicer(self._response_op, self._conf), server) server.add_insecure_port('[::]:{}'.format(self._port)) server.start() + self._run_grpc_gateway( + self._grpc_gateway_port) # start grpc_gateway server.wait_for_termination() def _run_server_func(self, bind_address, response_op, dag_conf, worker_idx): @@ -164,6 +193,7 @@ class ServerYamlConfChecker(object): "port": 9292, "worker_num": 1, "build_dag_each_worker": False, + "grpc_gateway_port": 0, "dag": {}, } @@ -171,6 +201,7 @@ class ServerYamlConfChecker(object): "port": int, "worker_num": int, "build_dag_each_worker": bool, + "grpc_gateway_port": int, } conf_qualification = { diff --git a/python/setup.py.app.in b/python/setup.py.app.in index 2b7ae930..4baf72e3 100644 --- a/python/setup.py.app.in +++ b/python/setup.py.app.in @@ -16,7 +16,6 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import platform import os from setuptools import setup, Distribution, Extension @@ -24,18 +23,9 @@ from setuptools import find_packages from setuptools import setup from paddle_serving_app.version import serving_app_version from pkg_resources import DistributionNotFound, get_distribution +import util -def python_version(): - return [int(v) for v in platform.python_version().split(".")] - -def find_package(pkgname): - try: - get_distribution(pkgname) - return True - except DistributionNotFound: - return False - -max_version, mid_version, min_version = python_version() +max_version, mid_version, min_version = util.python_version() if '${PACK}' == 'ON': copy_lib() diff --git a/python/setup.py.client.in b/python/setup.py.client.in index 96773c38..c1f143f0 100644 --- a/python/setup.py.client.in +++ b/python/setup.py.client.in @@ -16,7 +16,6 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import platform import os import sys @@ -25,19 +24,10 @@ from setuptools import find_packages from setuptools import setup from paddle_serving_client.version import serving_client_version from pkg_resources import DistributionNotFound, get_distribution +import util py_version = sys.version_info -def python_version(): - return [int(v) for v in platform.python_version().split(".")] - -def find_package(pkgname): - try: - get_distribution(pkgname) - return True - except DistributionNotFound: - return False - def copy_lib(): if py_version[0] == 2: lib_list = ['libpython2.7.so.1.0', 'libssl.so.10', 'libcrypto.so.10'] @@ -51,18 +41,20 @@ def copy_lib(): text = r.read() os.popen('cp {} ./paddle_serving_client/lib'.format(text.strip().split(' ')[1])) -max_version, mid_version, min_version = python_version() +max_version, mid_version, min_version = util.python_version() + +# gen pipeline proto code +util.gen_pipeline_code("paddle_serving_client") if '${PACK}' == 'ON': copy_lib() - REQUIRED_PACKAGES = [ 'six >= 1.10.0', 'protobuf >= 3.11.0', 'numpy >= 1.12', 'grpcio >= 1.28.1', 'grpcio-tools >= 1.28.1' ] -if not find_package("paddlepaddle") and not find_package("paddlepaddle-gpu"): +if not util.find_package("paddlepaddle") and not util.find_package("paddlepaddle-gpu"): REQUIRED_PACKAGES.append("paddlepaddle") diff --git a/python/setup.py.in b/python/setup.py.in index af7036bd..fa7051db 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -16,17 +16,14 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import platform - from setuptools import setup, Distribution, Extension from setuptools import find_packages from setuptools import setup from paddle_serving.version import serving_client_version +from grpc_tools import protoc +import util -def python_version(): - return [int(v) for v in platform.python_version().split(".")] - -max_version, mid_version, min_version = python_version() +max_version, mid_version, min_version = util.python_version() REQUIRED_PACKAGES = [ 'six >= 1.10.0', 'protobuf >= 3.1.0','paddlepaddle' diff --git a/python/setup.py.server.in b/python/setup.py.server.in index db679edb..38324309 100644 --- a/python/setup.py.server.in +++ b/python/setup.py.server.in @@ -16,25 +16,17 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import platform - from setuptools import setup, Distribution, Extension from setuptools import find_packages from setuptools import setup from paddle_serving_server.version import serving_server_version from pkg_resources import DistributionNotFound, get_distribution +import util -def find_package(pkgname): - try: - get_distribution(pkgname) - return True - except DistributionNotFound: - return False - -def python_version(): - return [int(v) for v in platform.python_version().split(".")] +max_version, mid_version, min_version = util.python_version() -max_version, mid_version, min_version = python_version() +# gen pipeline proto code +util.gen_pipeline_code("paddle_serving_server") REQUIRED_PACKAGES = [ 'six >= 1.10.0', 'protobuf >= 3.11.0', 'grpcio >= 1.28.1', 'grpcio-tools >= 1.28.1', diff --git a/python/setup.py.server_gpu.in b/python/setup.py.server_gpu.in index 4554c1d3..277cae6a 100644 --- a/python/setup.py.server_gpu.in +++ b/python/setup.py.server_gpu.in @@ -16,25 +16,17 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import platform - from setuptools import setup, Distribution, Extension from setuptools import find_packages from setuptools import setup from paddle_serving_server_gpu.version import serving_server_version from pkg_resources import DistributionNotFound, get_distribution +import util -def find_package(pkgname): - try: - get_distribution(pkgname) - return True - except DistributionNotFound: - return False - -def python_version(): - return [int(v) for v in platform.python_version().split(".")] +max_version, mid_version, min_version = util.python_version() -max_version, mid_version, min_version = python_version() +# gen pipeline proto code +util.gen_pipeline_code("paddle_serving_server_gpu") REQUIRED_PACKAGES = [ 'six >= 1.10.0', 'protobuf >= 3.11.0', 'grpcio >= 1.28.1', 'grpcio-tools >= 1.28.1', @@ -44,7 +36,9 @@ REQUIRED_PACKAGES = [ packages=['paddle_serving_server_gpu', 'paddle_serving_server_gpu.proto', 'paddle_serving_server_gpu.pipeline', - 'paddle_serving_server_gpu.pipeline.proto'] + 'paddle_serving_server_gpu.pipeline.proto', + 'paddle_serving_server_gpu.pipeline.gateway', + 'paddle_serving_server_gpu.pipeline.gateway.proto'] package_dir={'paddle_serving_server_gpu': '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu', @@ -53,7 +47,13 @@ package_dir={'paddle_serving_server_gpu': 'paddle_serving_server_gpu.pipeline': '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu/pipeline', 'paddle_serving_server_gpu.pipeline.proto': - '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu/pipeline/proto'} + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu/pipeline/proto', + 'paddle_serving_server_gpu.pipeline.gateway': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu/pipeline/gateway', + 'paddle_serving_server_gpu.pipeline.gateway.proto': + '${PADDLE_SERVING_BINARY_DIR}/python/paddle_serving_server_gpu/pipeline/gateway/proto'} + +package_data={'paddle_serving_server_gpu': ['pipeline/gateway/libproxy_server.so'],} setup( name='paddle-serving-server-gpu', @@ -65,6 +65,7 @@ setup( author_email='guru4elephant@gmail.com', install_requires=REQUIRED_PACKAGES, packages=packages, + package_data=package_data, package_dir=package_dir, # PyPI package information. classifiers=[ diff --git a/python/util.py b/python/util.py new file mode 100644 index 00000000..c3547c18 --- /dev/null +++ b/python/util.py @@ -0,0 +1,69 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from grpc_tools import protoc +import os +import platform + + +def python_version(): + return [int(v) for v in platform.python_version().split(".")] + + +def find_package(pkgname): + try: + get_distribution(pkgname) + return True + except DistributionNotFound: + return False + + +def gen_pipeline_code(package_name): + # pipeline service proto + protoc.main(( + '', + '-I.', + '--python_out=.', + '--grpc_python_out=.', + '{}/pipeline/proto/pipeline_service.proto'.format(package_name), )) + + # pipeline grpc-gateway proto + # *.pb.go + ret = os.system( + "cd {}/pipeline/gateway/proto/ && " + "../../../../../third_party/install/protobuf/bin/protoc -I. " + "-I$GOPATH/src " + "-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis " + "--go_out=plugins=grpc:. " + "gateway.proto".format(package_name)) + if ret != 0: + exit(1) + # *.gw.go + ret = os.system( + "cd {}/pipeline/gateway/proto/ && " + "../../../../../third_party/install/protobuf/bin/protoc -I. " + "-I$GOPATH/src " + "-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis " + "--grpc-gateway_out=logtostderr=true:. " + "gateway.proto".format(package_name)) + if ret != 0: + exit(1) + + # pipeline grpc-gateway shared-lib + ret = os.system( + "cd {}/pipeline/gateway && " + "go build -buildmode=c-shared -o libproxy_server.so proxy_server.go". + format(package_name)) + if ret != 0: + exit(1) diff --git a/tools/serving_build.sh b/tools/serving_build.sh index c54631a7..1078b004 100644 --- a/tools/serving_build.sh +++ b/tools/serving_build.sh @@ -19,6 +19,12 @@ function init() { cd Serving export SERVING_WORKDIR=$PWD $PYTHONROOT/bin/python -m pip install -r python/requirements.txt + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + + go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway + go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger + go get -u github.com/golang/protobuf/protoc-gen-go } function check_cmd() { -- GitLab