Pure-Python gRPC implementation for asyncio
===========================================
|project|_ |documentation|_ |version|_ |tag|_ |license|_
This project is based on `hyper-h2`_ and **requires Python >= 3.6**.
.. contents::
:local:
Example
~~~~~~~
See `examples`_ directory in the project's repository for all available
examples.
Client
------
.. code-block:: python3
import asyncio
from grpclib.client import Channel
# generated by protoc
from .helloworld_pb2 import HelloRequest, HelloReply
from .helloworld_grpc import GreeterStub
async def main():
loop = asyncio.get_event_loop()
channel = Channel('127.0.0.1', 50051, loop=loop)
greeter = GreeterStub(channel)
reply: HelloReply = await greeter.SayHello(HelloRequest(name='Dr. Strange'))
print(reply.message)
channel.close()
if __name__ == '__main__':
asyncio.run(main())
Server
------
.. code-block:: python3
import asyncio
from grpclib.utils import graceful_exit
from grpclib.server import Server
# generated by protoc
from .helloworld_pb2 import HelloRequest, HelloReply
from .helloworld_grpc import GreeterBase
class Greeter(GreeterBase):
async def SayHello(self, stream):
request: HelloRequest = await stream.recv_message()
message = f'Hello, {request.name}!'
await stream.send_message(HelloReply(message=message))
async def main(*, host='127.0.0.1', port=50051):
loop = asyncio.get_running_loop()
server = Server([Greeter()], loop=loop)
with graceful_exit([server], loop=loop):
await server.start(host, port)
print(f'Serving on {host}:{port}')
await server.wait_closed()
if __name__ == '__main__':
asyncio.run(main())
Installation
~~~~~~~~~~~~
.. code-block:: shell
$ pip3 install grpclib protobuf
Bug fixes and new features are frequently published via release candidates:
.. code-block:: shell
$ pip3 install --upgrade --pre grpclib
For the code generation you will also need a ``protoc`` compiler, which can be
installed with ``protobuf`` system package:
.. code-block:: shell
$ brew install protobuf # example for macOS users
$ protoc --version
libprotoc ...
**Or** you can use ``protoc`` compiler from the ``grpcio-tools`` Python package:
.. code-block:: shell
$ pip3 install grpcio-tools
$ python3 -m grpc_tools.protoc --version
libprotoc ...
**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/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 ``pip/setuptools`` into your ``$PATH`` during installation of the
``grpclib`` library.
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/
.. _examples: https://github.com/vmagamedov/grpclib/tree/master/example
.. |version| image:: https://img.shields.io/pypi/v/grpclib.svg?label=stable&color=green
.. _version: https://pypi.org/project/grpclib/
.. |license| image:: https://img.shields.io/pypi/l/grpclib.svg
.. _license: https://github.com/vmagamedov/grpclib/blob/master/LICENSE.txt
.. |tag| image:: https://img.shields.io/github/tag/vmagamedov/grpclib.svg?label=latest
.. _tag: https://pypi.org/project/grpclib/#history
.. |project| image:: https://img.shields.io/badge/vmagamedov%2Fgrpclib-blueviolet.svg?logo=github
.. _project: https://github.com/vmagamedov/grpclib
.. |documentation| image:: https://img.shields.io/badge/docs-grpclib.rtfd.io-blue.svg
.. _documentation: https://grpclib.readthedocs.io/en/latest/