Pure-Python gRPC implementation for asyncio
Go to file
Vladimir Magamedov 9933509804 Written about cancellation and deadlines into overview.rst 2018-04-01 04:30:40 +03:00
docs Written about cancellation and deadlines into overview.rst 2018-04-01 04:30:40 +03:00
example Simplified helloworld.proto file 2018-04-01 02:49:40 +03:00
grpclib Fixed deprecation warning and updated changelog 2018-04-01 00:44:34 +03:00
scripts Fixed release_check.sh script 2017-11-30 14:01:24 +02:00
tests Improved errors handling and logging on the server-side 2018-02-02 16:28:16 +02:00
.gitignore Refactoring, typing coverage, client example to test reconnection 2017-07-12 23:24:56 +03:00
.travis.yml Added CI configuration 2017-11-15 23:49:57 +02:00
LICENSE.txt Added sequence diagram to show how gRPC protocol in grpclib works 2018-03-31 21:51:45 +03:00
Makefile Prepared first release candidate for PyPI 2017-11-30 13:54:42 +02:00
README.rst Updated overview.rst page 2018-04-01 02:50:40 +03:00
pi.yaml Added documentation config 2017-11-30 14:53:09 +02:00
setup.cfg Channel now has dedicated request methods for every method type, more readable and simple stubs generation 2017-07-17 13:50:55 +03:00
setup.py Issued first release 2018-03-30 11:25:35 +03:00
tox.ini Added CI configuration 2017-11-15 23:49:57 +02:00

README.rst

This project is a pure-Python `gRPC`_ implementation, based on `hyper-h2`_
project, **requires Python >= 3.5**.

Motivation: ``grpclib`` is intended to implement gRPC protocol in Python once
for all concurrency models. However, currently ``grpclib`` supports only
``asyncio`` library and only with ``async/await`` syntax.

Note: Python 2.7 support is not planned, but you can use official `grpcio`_
library for projects with such requirements.

Installation
~~~~~~~~~~~~

.. code-block:: shell

    $ pip3 install grpclib

For the code generation you will also need a ``protoc`` compiler, which can be
installed with ``protobuf`` package:

.. code-block:: shell

    $ brew install protobuf  # example for macOS users

Or you can use ``protoc`` compiler from the ``grpcio-tools`` Python package:

.. code-block:: shell

    $ pip3 install grpcio-tools

**Note**: ``grpcio`` and ``grpcio-tools`` packages are **not required in
runtime**, ``grpcio-tools`` package will be used only during code generation.

Protoc plugin
~~~~~~~~~~~~~

In order to use this library you will have to generate special stub files using
plugin provided, which can be used like this:

.. code-block:: shell

    $ python3 -m grpc_tools.protoc -I. --python_out=. --python_grpc_out=. helloworld.proto

This command will generate ``helloworld_pb2.py`` and ``helloworld_grpc.py``
files.

Plugin, which implements ``--python_grpc_out`` option is available for
``protoc`` compiler as ``protoc-gen-python_grpc`` executable, which will be
installed by ``setuptools`` into your ``PATH`` during installation of the
``grpclib`` library.

Example
~~~~~~~

See ``example`` directory for a full example of the ``helloworld`` service.
``example/README.rst`` contains instructions about how to generate
``helloworld_pb2.py`` and ``helloworld_grpc.py`` files and how to run example.

Example basically looks like this:

.. code-block:: python

    import asyncio

    from grpclib.server import Server
    from grpclib.client import Channel

    from .helloworld_pb2 import HelloRequest, HelloReply
    from .helloworld_grpc import GreeterBase, GreeterStub

    loop = asyncio.get_event_loop()

    # Server

    class Greeter(GreeterBase):

        async def SayHello(self, stream):
            request = await stream.recv_message()
            message = 'Hello, {}!'.format(request.name)
            await stream.send_message(HelloReply(message=message))

    server = Server([Greeter()], loop=loop)
    loop.run_until_complete(server.start('127.0.0.1', 50051))

    # Client

    channel = Channel(loop=loop)
    stub = GreeterStub(channel)

    async def make_request():
        response = await stub.SayHello(HelloRequest(name='World'))
        assert response.message == 'Hello, World!'

    # Test request

    loop.run_until_complete(make_request())

    # Shutdown

    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()

Where ``helloworld.proto`` contains:

.. code-block:: protobuf

    syntax = "proto3";

    package helloworld;

    service Greeter {
        rpc SayHello (HelloRequest) returns (HelloReply) {}
    }

    message HelloRequest {
        string name = 1;
    }

    message HelloReply {
        string message = 1;
    }

Contributing
~~~~~~~~~~~~

Use Tox_ in order to test and lint your changes.

.. _gRPC: http://www.grpc.io
.. _hyper-h2: https://github.com/python-hyper/hyper-h2
.. _grpcio: https://pypi.org/project/grpcio/
.. _Tox: https://tox.readthedocs.io/