Add grpcio-admin Python package (#26166)

* Add grpcio-admin Python package

* Polish package content

* Make Linux artifact build happy

* Improve documentation
pull/26181/head
Lidi Zheng 4 years ago committed by GitHub
parent 88322f4e67
commit 25f5399b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      doc/python/sphinx/grpc_admin.rst
  2. 14
      doc/python/sphinx/grpc_csds.rst
  3. 2
      doc/python/sphinx/index.rst
  4. 6
      src/python/grpcio_admin/.gitignore
  5. 4
      src/python/grpcio_admin/MANIFEST.in
  6. 23
      src/python/grpcio_admin/README.rst
  7. 25
      src/python/grpcio_admin/grpc_admin/BUILD.bazel
  8. 42
      src/python/grpcio_admin/grpc_admin/__init__.py
  9. 17
      src/python/grpcio_admin/grpc_version.py
  10. 60
      src/python/grpcio_admin/setup.py
  11. 2
      src/python/grpcio_csds/.gitignore
  12. 10
      src/python/grpcio_csds/grpc_csds/__init__.py
  13. 26
      src/python/grpcio_tests/tests/admin/BUILD.bazel
  14. 55
      src/python/grpcio_tests/tests/admin/test_admin.py
  15. 19
      templates/src/python/grpcio_admin/grpc_version.py.template
  16. 5
      tools/distrib/python/grpc_prefixed/generate.py
  17. 9
      tools/run_tests/artifacts/build_artifact_python.sh
  18. 3
      tools/run_tests/helper_scripts/build_python.sh

@ -0,0 +1,14 @@
gRPC Admin
==========
What is gRPC Admin?
---------------------------------------------
It's a convenient API to improve the usability of creating a gRPC server with admin services to expose states in the gRPC library.
Design Document `gRPC Admin Interface <https://github.com/grpc/proposal/blob/master/A38-admin-interface-api.md>`_
Module Contents
---------------
.. automodule:: grpc_admin

@ -0,0 +1,14 @@
gRPC CSDS
=========
What is gRPC CSDS?
---------------------------------------------
In short, it's a xDS configuration dump protocol.
Design Document `gRPC CSDS <https://github.com/grpc/proposal/blob/master/A40-csds-support.md>`_
Module Contents
---------------
.. automodule:: grpc_csds

@ -11,7 +11,9 @@ API Reference
grpc
grpc_asyncio
grpc_admin
grpc_channelz
grpc_csds
grpc_health_checking
grpc_reflection
grpc_status

@ -0,0 +1,6 @@
*.proto
*_pb2.py
*_pb2_grpc.py
build/
grpcio_admin.egg-info/
dist/

@ -0,0 +1,4 @@
include grpc_version.py
recursive-include grpc_admin *.py
global-exclude *.pyc
include LICENSE

@ -0,0 +1,23 @@
gRPC Python Admin Interface Package
===================================
Debugging gRPC library can be a complex task. There are many configurations and
internal states, which will affect the behavior of the library. This Python
package will be the collection of admin services that are exposing debug
information. Currently, it includes:
* Channel tracing metrics (grpcio-channelz)
* Client Status Discovery Service (grpcio-csds)
Here is a snippet to create an admin server on "localhost:50051":
server = grpc.server(ThreadPoolExecutor())
port = server.add_insecure_port('localhost:50051')
grpc_admin.add_admin_servicers(self._server)
server.start()
Welcome to explore the admin services with CLI tool "grpcdebug":
https://github.com/grpc-ecosystem/grpcdebug.
For any issues or suggestions, please send to
https://github.com/grpc/grpc/issues.

@ -0,0 +1,25 @@
# Copyright 2021 The gRPC Authors
#
# 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.
package(default_visibility = ["//visibility:public"])
py_library(
name = "grpc_admin",
srcs = glob(["*.py"]),
imports = ["../"],
deps = [
"//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
"//src/python/grpcio_csds/grpc_csds",
],
)

@ -0,0 +1,42 @@
# Copyright 2021 The gRPC Authors
#
# 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.
"""gRPC Python's Admin interface."""
import grpc_csds
from grpc_channelz.v1 import channelz
def add_admin_servicers(server):
"""Register admin servicers to a server.
gRPC provides some predefined admin services to make debugging easier by
exposing gRPC's internal states. Each existing admin service is packaged as
a separate library, and the documentation of the predefined admin services
is usually scattered. It can be time consuming to get the dependency
management, module initialization, and library import right for each one of
them.
This API provides a convenient way to create a gRPC server to expose admin
services. With this, any new admin services that you may add in the future
are automatically available via the admin interface just by upgrading your
gRPC version.
Args:
server: A gRPC server to which all admin services will be added.
"""
channelz.add_channelz_servicer(server)
grpc_csds.add_csds_servicer(server)
__all__ = ['add_admin_servicers']

@ -0,0 +1,17 @@
# Copyright 2021 The gRPC Authors
#
# 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.
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_admin/grpc_version.py.template`!!!
VERSION = '1.38.0.dev0'

@ -0,0 +1,60 @@
# Copyright 2021 The gRPC Authors
#
# 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.
"""Setup module for admin interface in gRPC Python."""
import os
import sys
import setuptools
_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__))
_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst')
# Ensure we're in the proper directory whether or not we're being used by pip.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
# Break import-style to ensure we can actually find our local modules.
import grpc_version
CLASSIFIERS = [
'Development Status :: 5 - Production/Stable',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'License :: OSI Approved :: Apache Software License',
]
PACKAGE_DIRECTORIES = {
'': '.',
}
INSTALL_REQUIRES = (
'grpcio-channelz>={version}'.format(version=grpc_version.VERSION),
'grpcio-csds>={version}'.format(version=grpc_version.VERSION),
)
SETUP_REQUIRES = INSTALL_REQUIRES
setuptools.setup(name='grpcio-admin',
version=grpc_version.VERSION,
license='Apache License 2.0',
description='a collection of admin services',
long_description=open(_README_PATH, 'r').read(),
author='The gRPC Authors',
author_email='grpc-io@googlegroups.com',
classifiers=CLASSIFIERS,
url='https://grpc.io',
package_dir=PACKAGE_DIRECTORIES,
packages=setuptools.find_packages('.'),
install_requires=INSTALL_REQUIRES,
setup_requires=SETUP_REQUIRES)

@ -2,5 +2,5 @@
*_pb2.py
*_pb2_grpc.py
build/
grpcio_channelz.egg-info/
grpcio_csds.egg-info/
dist/

@ -42,6 +42,16 @@ class ClientStatusDiscoveryServiceServicer(
def add_csds_servicer(server):
"""Register CSDS servicer to a server.
CSDS is part of xDS protocol used to expose in-effective traffic
configuration (or xDS resources). It focuses on simplify the debugging of
unexpected routing behaviors, which could be due to a misconfiguration,
unhealthy backends or issues in the control or data plane.
Args:
server: A gRPC server to which the CSDS service will be added.
"""
csds_pb2_grpc.add_ClientStatusDiscoveryServiceServicer_to_server(
ClientStatusDiscoveryServiceServicer(), server)

@ -0,0 +1,26 @@
# Copyright 2021 The gRPC Authors
#
# 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.
load("//bazel:python_rules.bzl", "py2and3_test")
py2and3_test(
name = "test_admin",
size = "small",
srcs = ["test_admin.py"],
main = "test_admin.py",
deps = [
"//src/python/grpcio/grpc:grpcio",
"//src/python/grpcio_admin/grpc_admin",
],
)

@ -0,0 +1,55 @@
# Copyright 2021 The gRPC Authors
#
# 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.
"""A test to ensure that admin services are registered correctly."""
import logging
import unittest
from concurrent.futures import ThreadPoolExecutor
import grpc
import grpc_admin
from grpc_csds import csds_pb2, csds_pb2_grpc
from grpc_channelz.v1 import channelz_pb2, channelz_pb2_grpc
class TestAdmin(unittest.TestCase):
def setUp(self):
self._server = grpc.server(ThreadPoolExecutor())
port = self._server.add_insecure_port('localhost:0')
grpc_admin.add_admin_servicers(self._server)
self._server.start()
self._channel = grpc.insecure_channel('localhost:%s' % port)
def tearDown(self):
self._channel.close()
self._server.stop(0)
def test_has_csds(self):
stub = csds_pb2_grpc.ClientStatusDiscoveryServiceStub(self._channel)
resp = stub.FetchClientStatus(csds_pb2.ClientStatusRequest())
# No exception raised and the response is valid
self.assertGreater(len(resp.config), 0)
def test_has_channelz(self):
stub = channelz_pb2_grpc.ChannelzStub(self._channel)
resp = stub.GetTopChannels(channelz_pb2.GetTopChannelsRequest())
# No exception raised and the response is valid
self.assertGreater(len(resp.channel), 0)
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
unittest.main(verbosity=2)

@ -0,0 +1,19 @@
%YAML 1.2
--- |
# Copyright 2021 The gRPC Authors
#
# 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.
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_admin/grpc_version.py.template`!!!
VERSION = '${settings.python_version.pep440()}'

@ -139,6 +139,11 @@ def main():
name_long='gRPC Client Status Discovery Service',
destination_package='grpcio-csds'))
generate_package(
PackageMeta(name='grpc-admin',
name_long='gRPC Admin Interface',
destination_package='grpcio-admin'))
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)

@ -188,6 +188,15 @@ then
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_csds/setup.py \
sdist bdist_wheel
cp -r src/python/grpcio_csds/dist/* "$ARTIFACT_DIR"
# Build grpcio_admin source distribution and it needs the cutting-edge version
# of Channelz and CSDS to be installed.
"${PIP}" install --upgrade xds-protos==0.0.8
"${PIP}" install grpcio-channelz --no-index --find-links "file://$ARTIFACT_DIR/"
"${PIP}" install grpcio-csds --no-index --find-links "file://$ARTIFACT_DIR/"
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_admin/setup.py \
sdist bdist_wheel
cp -r src/python/grpcio_admin/dist/* "$ARTIFACT_DIR"
fi
if [ "$GRPC_SKIP_TWINE_CHECK" == "" ]

@ -223,6 +223,9 @@ pip_install_dir "$ROOT/src/python/grpcio_status"
# Build/install csds
pip_install_dir "$ROOT/src/python/grpcio_csds"
# Build/install admin
pip_install_dir "$ROOT/src/python/grpcio_admin"
# Install testing
pip_install_dir "$ROOT/src/python/grpcio_testing"

Loading…
Cancel
Save