rpcx


Namerpcx JSON
Version 0.3.0 PyPI version JSON
download
home_pagehttps://github.com/uSpike/rpcx
SummaryAsynchronous RPC client/server with streaming support
upload_time2023-11-01 18:26:43
maintainer
docs_urlNone
authorJordan Speicher
requires_python>=3.8,<4.0
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # RPCx

[![CI](https://github.com/uSpike/rpcx/actions/workflows/main.yml/badge.svg)](https://github.com/uSpike/rpcx/actions/workflows/main.yml)

Asynchronous RPC server/client for Python 3.8+ with streaming support.

- Async backend implemented by `anyio` providing support for `asyncio` and `trio`.
- Generic stream support for transport includes Websockets.
- Messages are serialized with `msgpack`.

```python
import math

import anyio
from anyio.streams.stapled import StapledObjectStream
from rpcx import RPCClient, RPCManager, RPCServer, Stream


async def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b


async def fibonacci(n: int, stream: Stream) -> None:
    """Stream each number as computed in the Fibonacci sequence for a given starting number"""
    a, b = 0, 1

    for i in range(n):
        await stream.send(i)
        a, b = b, a + b


async def sum(stream: Stream) -> int:
    """Stream numbers from client and return the sum"""
    total = 0

    async for num in stream:
        total += num

    return total


manager = RPCManager()
manager.register("add", add)
manager.register("fibonacci", fibonacci)
manager.register("sum", sum)


async def main() -> None:
    # Create two connected stapled streams to simulate a network connection
    server_send, server_receive = anyio.create_memory_object_stream[bytes](math.inf)
    client_send, client_receive = anyio.create_memory_object_stream[bytes](math.inf)
    server_stream = StapledObjectStream(client_send, server_receive)
    client_stream = StapledObjectStream(server_send, client_receive)

    server = RPCServer(server_stream, manager)

    async with anyio.create_task_group() as task_group:
        task_group.start_soon(server.serve)

        async with RPCClient(client_stream) as client:
            # Simple method call
            assert await client.request("add", 1, 2) == 3

            # Streaming (server to client) example
            async with client.request_stream("fibonacci", 6) as stream:
                async for num in stream:
                    print(num)  # 1, 1, 2, 3, 5, 8

            # Streaming (client to server) example
            async with client.request_stream("sum") as stream:
                for num in range(10):
                    await stream.send(num)

            assert await stream == 45


anyio.run(main)
```

# Development

## Installation

Run `poetry install` to install the project.

## Execute tests

Execute `poetry run tox` to run tests for all python environments.

## Pre-commit hooks

Execute `poetry run pre-commit run -a` to run all linters, formatters, and checks.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/uSpike/rpcx",
    "name": "rpcx",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "Jordan Speicher",
    "author_email": "jordan@jspeicher.com",
    "download_url": "https://files.pythonhosted.org/packages/1a/98/7df392cc4d9b4f19642bc3e2b89451a568e53b187127b8467a0a072d9e5f/rpcx-0.3.0.tar.gz",
    "platform": null,
    "description": "# RPCx\n\n[![CI](https://github.com/uSpike/rpcx/actions/workflows/main.yml/badge.svg)](https://github.com/uSpike/rpcx/actions/workflows/main.yml)\n\nAsynchronous RPC server/client for Python 3.8+ with streaming support.\n\n- Async backend implemented by `anyio` providing support for `asyncio` and `trio`.\n- Generic stream support for transport includes Websockets.\n- Messages are serialized with `msgpack`.\n\n```python\nimport math\n\nimport anyio\nfrom anyio.streams.stapled import StapledObjectStream\nfrom rpcx import RPCClient, RPCManager, RPCServer, Stream\n\n\nasync def add(a: int, b: int) -> int:\n    \"\"\"Add two numbers\"\"\"\n    return a + b\n\n\nasync def fibonacci(n: int, stream: Stream) -> None:\n    \"\"\"Stream each number as computed in the Fibonacci sequence for a given starting number\"\"\"\n    a, b = 0, 1\n\n    for i in range(n):\n        await stream.send(i)\n        a, b = b, a + b\n\n\nasync def sum(stream: Stream) -> int:\n    \"\"\"Stream numbers from client and return the sum\"\"\"\n    total = 0\n\n    async for num in stream:\n        total += num\n\n    return total\n\n\nmanager = RPCManager()\nmanager.register(\"add\", add)\nmanager.register(\"fibonacci\", fibonacci)\nmanager.register(\"sum\", sum)\n\n\nasync def main() -> None:\n    # Create two connected stapled streams to simulate a network connection\n    server_send, server_receive = anyio.create_memory_object_stream[bytes](math.inf)\n    client_send, client_receive = anyio.create_memory_object_stream[bytes](math.inf)\n    server_stream = StapledObjectStream(client_send, server_receive)\n    client_stream = StapledObjectStream(server_send, client_receive)\n\n    server = RPCServer(server_stream, manager)\n\n    async with anyio.create_task_group() as task_group:\n        task_group.start_soon(server.serve)\n\n        async with RPCClient(client_stream) as client:\n            # Simple method call\n            assert await client.request(\"add\", 1, 2) == 3\n\n            # Streaming (server to client) example\n            async with client.request_stream(\"fibonacci\", 6) as stream:\n                async for num in stream:\n                    print(num)  # 1, 1, 2, 3, 5, 8\n\n            # Streaming (client to server) example\n            async with client.request_stream(\"sum\") as stream:\n                for num in range(10):\n                    await stream.send(num)\n\n            assert await stream == 45\n\n\nanyio.run(main)\n```\n\n# Development\n\n## Installation\n\nRun `poetry install` to install the project.\n\n## Execute tests\n\nExecute `poetry run tox` to run tests for all python environments.\n\n## Pre-commit hooks\n\nExecute `poetry run pre-commit run -a` to run all linters, formatters, and checks.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Asynchronous RPC client/server with streaming support",
    "version": "0.3.0",
    "project_urls": {
        "Homepage": "https://github.com/uSpike/rpcx",
        "Repository": "https://github.com/uSpike/rpcx"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9855a17c5361133e1d607e9c544a8b5281641093bcf0451296e0bcfef4217b19",
                "md5": "100b8c49a486be8890d806b89a8fc255",
                "sha256": "62600569a38d2a314f496b1b28da2f46b913a77f3c7211b968b69ac1d71cc218"
            },
            "downloads": -1,
            "filename": "rpcx-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "100b8c49a486be8890d806b89a8fc255",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 9978,
            "upload_time": "2023-11-01T18:26:41",
            "upload_time_iso_8601": "2023-11-01T18:26:41.870207Z",
            "url": "https://files.pythonhosted.org/packages/98/55/a17c5361133e1d607e9c544a8b5281641093bcf0451296e0bcfef4217b19/rpcx-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1a987df392cc4d9b4f19642bc3e2b89451a568e53b187127b8467a0a072d9e5f",
                "md5": "f19a21b6d51ed9150dce3ac4fdd5c111",
                "sha256": "f67e50c7d0438269c0acb845309b129e81778939015535cc46f0c51f28533551"
            },
            "downloads": -1,
            "filename": "rpcx-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f19a21b6d51ed9150dce3ac4fdd5c111",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 9327,
            "upload_time": "2023-11-01T18:26:43",
            "upload_time_iso_8601": "2023-11-01T18:26:43.244773Z",
            "url": "https://files.pythonhosted.org/packages/1a/98/7df392cc4d9b4f19642bc3e2b89451a568e53b187127b8467a0a072d9e5f/rpcx-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-01 18:26:43",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "uSpike",
    "github_project": "rpcx",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "rpcx"
}
        
Elapsed time: 0.18635s