# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['trio_jsonrpc', 'trio_jsonrpc.transport']

package_data = \
{'': ['*']}

install_requires = \
['sansio-jsonrpc==0.1.0', 'trio-websocket>=0.8.0,<0.9.0']

setup_kwargs = {
    'name': 'trio-jsonrpc',
    'version': '0.1.0',
    'description': 'JSON-RPC v2.0 for Trio',
    'long_description': '# JSON-RPC v2.0 for Trio\n\nThis project provides an implementation of [JSON-RPC v\n2.0](https://www.jsonrpc.org/specification) based on\n[sansio-jsonrpc](https://github.com/hyperiongray/sansio-jsonrpc) with all of the I/O\nimplemented using the [Trio asynchronous framework](https://trio.readthedocs.io).\n\n## Client Example\n\nThe following example shows a basic JSON-RPC client.\n\n```python\nfrom trio_jsonrpc import open_jsonrpc_ws, JsonRpcException\n\nasync def main():\n    async with open_jsonrpc_ws(\'ws://example.com/\') as client:\n        try:\n            resp = await client.request(\n                method=\'open_vault_door\',\n                {\'employee\': \'Mark\', \'pin\': 1234}\n            )\n            print(resp.result)\n\n            await client.notify(method=\'hello_world\')\n        except JsonRpcException as jre:\n            print(\'RPC failed:\', jre)\n\ntrio.run(main)\n```\n\nThe example begins by opening a JSON-RPC connection using a WebSocket transport. The\nimplementation is designed to support multiple types of transport, but currently\nWebSocket transport is the only one that has been implemented.\n\n> Note that JSON-RPC does not contain any framing logic, i.e. a specification for how to\n> identify message boundaries within a stream. Therefore, if you want to use JSON-RPC\n> with raw TCP sockets, you either need to add your own framing logic or else use a\n> streaming JSON parser. For this reason, we have chosen to focus on WebSocket transport\n> initially, because WebSocket does include framing.\n\nThe connection is opened inside a context manager that guarantees the connection is\nready when entering the block and automatically closes the connection when leaving the\nblock.\n\nWithin the block, we call the client\'s `request(...)` method to send a JSON-RPC request.\nThis method sends the request to the server, waits for a response, and returns a\n`JsonRpcResponse` object. If the server indicates that an error occurred, a\n`JsonRpcException` will be raised instead. The client multiplexes requests so that it\ncan be use concurrently from multiple tasks; responses are routed back to the\nappropriate task that called `request(...)`.\n\nThe client also has a `notify(...)` method which sends a request to the server but does\nnot expect or wait for a response.\n\n## Server Example\n\nThe following example shows a basic JSON-RPC server. The server is more DIY (do it\nyourself) than the client because a server has to incorporate several disparate\nfunctionalities:\n\n1. Setting up the transport, especially if the transport requires a handshake as\n   WebSocket does.\n2. Handling new connections to the server.\n3. Multiplexing requests on a single connection.\n4. Dispatching a request to an appropriate handler.\n5. Managing connection state over the course of multiple requests. (I.e. allowing one\n   handler to indicate that the connection is authorized, so other handlers can use that\n   authorization information to make access control decisions.)\n6. Possibly logging information about each request.\n\nThis library cannot feasibly implement a default solution that handles the\naforementioned items in a way that satsifies every downstream project. Instead, the\nlibrary gives you the pieces you need to build a server.\n\n```python\nfrom dataclasses import dataclass\nimport trio\nfrom trio_jsonrpc import Dispatch, JsonRpcApplicationError\nimport trio_websocket\n\n@dataclass\nclass RequestContext:\n    """ A sample implementation for request context. """\n    db: typing.Any = None\n    authorized_employee: str = None\n\ndispatch = Dispatch()\n\n@dispatch.handler\nasync def open_vault_door(context, employee, pin):\n    access = await context.db.check_pin(employee, pin)\n    if access:\n        context.authorized_employee = employee\n        return {"door_open": True}\n    else:\n        context.authorized_employee = None\n        raise JsonRpcApplicationError(code=-1, message="Not authorized.")\n\n@dispatch.handler\nasync def close_vault_door(context):\n    context.authorized_employee = None\n    return {"door_open": False}\n\nasync def main():\n    db = ...\n    base_context = RequestContext(db=db)\n\n    async def responder(conn, recv_channel):\n        async for result in recv_channel:\n            if\n\n    async def connection_handler(ws_request):\n        ws = await ws_request.accept()\n        transport = WebSocketTransport(ws)\n        rpc_conn = JsonRpcConnection(transport, JsonRpcConnectionType.SERVER)\n        conn_context = copy(base_context)\n        async with trio.open_nursery() as nursery:\n            nursery.start_soon(rpc_conn._background_task)\n            async for request in rpc_conn.iter_requests():\n                nursery.start_soon(dispatch, request, conn_context)\n            nursery.cancel_scope.cancel()\n\n    await trio_websocket.serve_websocket(connection_handler, \'localhost\', 8000, None)\n\ntrio.run(main)\n```\n\nThis example defines a `RequestContext` class which is used to share state between\nrequests on the same connection. Next, a `Dispatch` object is created, which is used to\nmap JSON-RPC methods to Python functions. The `@dispatch.handler` decorator\nautomatically registers a Python function as a JSON-RPC method of the same name. Each\nof these handlers takes a `context` object as well as the parameters included in the\nJSON-RPC request. The use of the dispatch and/or context systems are entirely optional.\n\nIn `main()`, we set up a new WebSocket server. For each new connection, we complete the\nWebSocket handshake and then wrap the connection in a `JsonRpcConnection`. Finally, we\niterate over the incoming JSON-RPC requsts and dispatch each one inside a new task.\n',
    'author': 'Mark E. Haase',
    'author_email': 'mehaase@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/hyperiongray/trio-jsonrpc',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
