Metadata-Version: 2.1
Name: purerpc
Version: 0.3.2
Summary: Asynchronous pure Python gRPC client and server implementation supporting asyncio, uvloop, curio and trio
Home-page: https://github.com/standy66/purerpc
Author: Andrew Stepanov
License: Apache License Version 2.0
Keywords: async,await,grpc,pure-python,pypy,network,rpc,http2
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Telecommunications Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: MacOS
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX :: BSD
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Framework :: AsyncIO
Classifier: Framework :: Trio
Classifier: Framework :: Pytest
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Requires-Python: >=3.5
Description-Content-Type: text/markdown
Requires-Dist: h2 (<4,>=3.1.0)
Requires-Dist: protobuf (~=3.6)
Requires-Dist: anyio (<2,>=1.0.0b2)
Requires-Dist: async-exit-stack (<2,>=1.0.1)
Requires-Dist: tblib (<2,>=1.3.2)
Requires-Dist: async-generator (<2.0,>=1.10)
Requires-Dist: python-forge (~=18.6)

# purerpc

[![Build Status](https://img.shields.io/travis/standy66/purerpc.svg?style=flat)](https://travis-ci.org/standy66/purerpc)
[![PyPI version](https://img.shields.io/pypi/v/purerpc.svg?style=flat)](https://pypi.org/project/purerpc/)
[![Downloads](https://pepy.tech/badge/purerpc/month)](https://pepy.tech/project/purerpc)

Asynchronous pure Python gRPC client and server implementation supporting
[asyncio](https://docs.python.org/3/library/asyncio.html),
[uvloop](https://github.com/MagicStack/uvloop),
[curio](https://github.com/dabeaz/curio) and
[trio](https://github.com/python-trio/trio) (achieved with [anyio](https://github.com/agronholm/anyio) compatibility layer).

## Requirements

* CPython >= 3.5
* PyPy >= 3.5

## Installation

Latest PyPI version:

```bash
pip install purerpc
```

Latest development version:

```bash
pip install git+https://github.com/standy66/purerpc.git
```

By default purerpc uses asyncio event loop, if you want to use uvloop, curio or trio, please install them manually.

## protoc plugin

purerpc adds `protoc-gen-purerpc` plugin for `protoc` to your `PATH` enviroment variable
so you can use it to generate service definition and stubs: 

```bash
protoc --purerpc_out=. --python_out=. -I. greeter.proto
```

or, if you installed `grpcio_tools` Python package:

```bash
python -m grpc_tools.protoc --purerpc_out=. --python_out=. -I. greeter.proto
```

## Usage

NOTE: `greeter_grpc` module is generated by purerpc's `protoc-gen-purerpc` plugin.

Below are the examples for Python 3.6 and above which introduced asynchronous generators as a language concept.
For Python 3.5, where native asynchronous generators are not supported, you can use [async_generator](https://github.com/python-trio/async_generator) library for this purpose.
Just mark yielding coroutines with `@async_generator` decorator and use `await yield_(value)` and `await yield_from_(async_iterable)` instead of `yield`.

### Server

```python
from greeter_pb2 import HelloRequest, HelloReply
from greeter_grpc import GreeterServicer
from purerpc import Server


class Greeter(GreeterServicer):
    async def SayHello(self, message):
        return HelloReply(message="Hello, " + message.name)

    async def SayHelloToMany(self, input_messages):
        async for message in input_messages:
            yield HelloReply(message=f"Hello, {message.name}")


server = Server(50055)
server.add_service(Greeter().service)
server.serve(backend="asyncio")  # backend can also be one of: "uvloop", "curio", "trio"
```

### Client

```python
import anyio
import purerpc
from greeter_pb2 import HelloRequest, HelloReply
from greeter_grpc import GreeterStub


async def gen():
    for i in range(5):
        yield HelloRequest(name=str(i))


async def main():
    async with purerpc.insecure_channel("localhost", 50055) as channel:
        stub = GreeterStub(channel)
        reply = await stub.SayHello(HelloRequest(name="World"))
        print(reply.message)

        async for reply in stub.SayHelloToMany(gen()):
            print(reply.message)


if __name__ == "__main__":
    anyio.run(main, backend="asyncio")  # backend can also be one of: "uvloop", "curio", "trio"
```

You can mix server and client code, for example make a server that requests something using purerpc from another gRPC server, etc.

More examples in `misc/` folder

# [Release 0.3.2](https://github.com/standy66/purerpc/compare/v0.3.1...v0.3.2) (2019-02-15)


### Bug Fixes

* fix dependencies, remove some of anyio monkey patches ([ac6c5c2](https://github.com/standy66/purerpc/commit/ac6c5c2))



# [Release 0.3.1](https://github.com/standy66/purerpc/compare/v0.3.0...v0.3.1) (2019-02-15)


### Bug Fixes

* fix pickling error in purerpc.test_utils._WrappedResult ([9f0a63d](https://github.com/standy66/purerpc/commit/9f0a63d))



# [Release 0.3.0](https://github.com/standy66/purerpc/compare/v0.2.1...v0.3.0) (2019-02-14)


### Features

* expose new functions in purerpc.test_utils ([07b10e1](https://github.com/standy66/purerpc/commit/07b10e1))
* migrate to pytest ([95c0a8b](https://github.com/standy66/purerpc/commit/95c0a8b))


### BREAKING CHANGES

* purerpc.test_utils.PureRPCTestCase is removed



# [Release 0.2.0](https://github.com/standy66/purerpc/compare/v0.1.6...v0.2.0) (2019-02-10)


### Features

* add backend option to Server.serve ([5f47f8e](https://github.com/standy66/purerpc/commit/5f47f8e))
* add support for Python 3.5 ([a681192](https://github.com/standy66/purerpc/commit/a681192))
* improved exception handling in test utils ([b1df796](https://github.com/standy66/purerpc/commit/b1df796))
* migrate to anyio ([746b1c2](https://github.com/standy66/purerpc/commit/746b1c2))


### BREAKING CHANGES

* Server and test now use asyncio event loop by default,
this behaviour can be changed with PURERPC_BACKEND environment variable
* purerpc.Channel is removed, migrate to
purerpc.insecure_channel async context manager (now supports correct
shutdown)

## Release 0.1.6

* Allow passing request headers to method handlers in request argument
* Allow passing custom metadata to method stub calls (in metadata optional keyword argument)

## Release 0.1.5

* Enforce SO_KEEPALIVE with small timeouts
* Expose PureRPCTestCase in purerpc API for unit testing purerpc services

## Release 0.1.4

* Speed up protoc plugin

## Release 0.1.3 [PyPI only]

* Fix long description on PyPI

## Release 0.1.2

* Fix unit tests on Python 3.7

## Release 0.1.0

* Implement immediate mode

## Release 0.0.1

* Initial release


