# WSRPC aiohttp
[![Github Actions](https://github.com/wsrpc/wsrpc-aiohttp/workflows/tests/badge.svg)](https://github.com/wsrpc/wsrpc-aiohttp/actions?query=branch%3Amaster)
[![Coveralls](https://coveralls.io/repos/github/wsrpc/wsrpc-aiohttp/badge.svg?branch=master)](https://coveralls.io/github/wsrpc/wsrpc-aiohttp?branch=master)
[![Latest Version](https://img.shields.io/pypi/v/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)
[![python wheel](https://img.shields.io/pypi/wheel/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)
[![Python Versions](https://img.shields.io/pypi/pyversions/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)
[![license](https://img.shields.io/pypi/l/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)
Easy to use minimal WebSocket Remote Procedure Call library for aiohttp
servers.
See [online demo](https://demo.wsrpc.info/) and
[documentation](https://docs.wsrpc.info/) with examples.
## Features
- Call server functions from the client side;
- Call client functions from the server (for example to notify clients
about events);
- Async connection protocol: both server or client are able to call
several functions and get responses as soon as each response would
be ready in any order.
- Fully async server-side functions;
- Transfer any exceptions from a client side to the server side and
vise versa;
- Ready-to-use frontend-library without dependencies;
- Thread-based websocket handler for writing fully-synchronous backend
code (for synchronous database drivers etc.)
- Protected server-side methods (cliens are not able to call methods,
starting with underline directly);
- Signals for introspection
## Installation
Install via pip:
pip install wsrpc-aiohttp
You may want to install *optional*
[ujson](https://pypi.python.org/pypi/ujson) library to speedup message
serialization/deserialization:
pip install ujson
Python module provides client js library out of the box. But for pure
javascript applications you can install [standalone js client
library](https://www.npmjs.com/package/@wsrpc/client) using npm:
npm install @wsrpc/client
## Usage
Backend code:
``` python
import logging
from time import time
import aiohttp.web
from wsrpc_aiohttp import Route, STATIC_DIR, WebSocketRoute, decorators
log = logging.getLogger(__name__)
# This class can be called by client.
# Connection object will have this class instance after calling route-alias.
class TestRoute(Route):
# This method will be executed when client calls route-alias
# for the first time.
def init(self, **kwargs):
# Python __init__ must be return "self".
# This method might return anything.
return kwargs
# This method named by camelCase because the client can call it.
@decorators.proxy
async def getEpoch(self):
# You can execute functions on the client side
await self.do_notify()
return time()
# This method calls function on the client side
@decorators.proxy
async def do_notify(self):
awesome = 'Somebody executed test1.getEpoch method!'
await self.socket.call('notify', result=awesome)
app = aiohttp.web.Application()
app.router.add_route("*", "/ws/", WebSocketAsync) # Websocket route
app.router.add_static('/js', STATIC_DIR) # WSRPC js library
app.router.add_static('/', ".") # Your static files
# Stateful request
# This is the route alias TestRoute as "test1"
WebSocketAsync.add_route('test1', TestRoute)
# Stateless request
WebSocketAsync.add_route('test2', lambda *a, **kw: True)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
aiohttp.web.run_app(app, port=8000)
```
Frontend code:
``` HTML
<script type="text/javascript" src="/js/wsrpc.min.js"></script>
<script>
var url = (window.location.protocol==="https):"?"wss://":"ws://") + window.location.host + '/ws/';
RPC = new WSRPC(url, 8000);
// Configure client API, that can be called from server
RPC.addRoute('notify', function (data) {
console.log('Server called client route "notify":', data);
return data.result;
});
RPC.connect();
// Call stateful route
// After you call that route, server would execute 'notify' route on the
// client, that is registered above.
RPC.call('test1.getEpoch').then(function (data) {
console.log('Result for calling server route "test1.getEpoch": ', data);
}, function (error) {
alert(error);
});
// Call stateless method
RPC.call('test2').then(function (data) {
console.log('Result for calling server route "test2"', data);
});
</script>
```
## Versioning
This software follows [Semantic Versioning](http://semver.org/)
Raw data
{
"_id": null,
"home_page": "https://github.com/wsrpc/wsrpc-aiohttp",
"name": "wsrpc-aiohttp",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7, <4",
"maintainer_email": "",
"keywords": "",
"author": "Dmitry Orlov <me@mosquito.su>",
"author_email": "me@mosquito.su",
"download_url": "https://files.pythonhosted.org/packages/4c/4b/d5b3ef27a9073498ce93a5002e8feaf758159093bd0a0c048dc9bf2a72c4/wsrpc-aiohttp-4.0.2.tar.gz",
"platform": "all",
"description": "# WSRPC aiohttp\n\n[![Github Actions](https://github.com/wsrpc/wsrpc-aiohttp/workflows/tests/badge.svg)](https://github.com/wsrpc/wsrpc-aiohttp/actions?query=branch%3Amaster)\n\n[![Coveralls](https://coveralls.io/repos/github/wsrpc/wsrpc-aiohttp/badge.svg?branch=master)](https://coveralls.io/github/wsrpc/wsrpc-aiohttp?branch=master)\n\n[![Latest Version](https://img.shields.io/pypi/v/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)\n\n[![python wheel](https://img.shields.io/pypi/wheel/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)\n\n[![Python Versions](https://img.shields.io/pypi/pyversions/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)\n\n[![license](https://img.shields.io/pypi/l/wsrpc-aiohttp.svg)](https://pypi.python.org/pypi/wsrpc-aiohttp/)\n\nEasy to use minimal WebSocket Remote Procedure Call library for aiohttp\nservers.\n\nSee [online demo](https://demo.wsrpc.info/) and\n[documentation](https://docs.wsrpc.info/) with examples.\n\n## Features\n\n- Call server functions from the client side;\n- Call client functions from the server (for example to notify clients\n about events);\n- Async connection protocol: both server or client are able to call\n several functions and get responses as soon as each response would\n be ready in any order.\n- Fully async server-side functions;\n- Transfer any exceptions from a client side to the server side and\n vise versa;\n- Ready-to-use frontend-library without dependencies;\n- Thread-based websocket handler for writing fully-synchronous backend\n code (for synchronous database drivers etc.)\n- Protected server-side methods (cliens are not able to call methods,\n starting with underline directly);\n- Signals for introspection\n\n## Installation\n\nInstall via pip:\n\n pip install wsrpc-aiohttp\n\nYou may want to install *optional*\n[ujson](https://pypi.python.org/pypi/ujson) library to speedup message\nserialization/deserialization:\n\n pip install ujson\n\nPython module provides client js library out of the box. But for pure\njavascript applications you can install [standalone js client\nlibrary](https://www.npmjs.com/package/@wsrpc/client) using npm:\n\n npm install @wsrpc/client\n\n## Usage\n\nBackend code:\n\n``` python\nimport logging\nfrom time import time\n\nimport aiohttp.web\nfrom wsrpc_aiohttp import Route, STATIC_DIR, WebSocketRoute, decorators\n\n\nlog = logging.getLogger(__name__)\n\n\n# This class can be called by client.\n# Connection object will have this class instance after calling route-alias.\nclass TestRoute(Route):\n # This method will be executed when client calls route-alias\n # for the first time.\n def init(self, **kwargs):\n # Python __init__ must be return \"self\".\n # This method might return anything.\n return kwargs\n\n # This method named by camelCase because the client can call it.\n @decorators.proxy\n async def getEpoch(self):\n\n # You can execute functions on the client side\n await self.do_notify()\n\n return time()\n\n # This method calls function on the client side\n @decorators.proxy\n async def do_notify(self):\n awesome = 'Somebody executed test1.getEpoch method!'\n await self.socket.call('notify', result=awesome)\n\n\napp = aiohttp.web.Application()\napp.router.add_route(\"*\", \"/ws/\", WebSocketAsync) # Websocket route\napp.router.add_static('/js', STATIC_DIR) # WSRPC js library\napp.router.add_static('/', \".\") # Your static files\n\n# Stateful request\n# This is the route alias TestRoute as \"test1\"\nWebSocketAsync.add_route('test1', TestRoute)\n\n# Stateless request\nWebSocketAsync.add_route('test2', lambda *a, **kw: True)\n\n\nif __name__ == '__main__':\n logging.basicConfig(level=logging.DEBUG)\n aiohttp.web.run_app(app, port=8000)\n```\n\nFrontend code:\n\n``` HTML\n<script type=\"text/javascript\" src=\"/js/wsrpc.min.js\"></script>\n<script>\n var url = (window.location.protocol===\"https):\"?\"wss://\":\"ws://\") + window.location.host + '/ws/';\n RPC = new WSRPC(url, 8000);\n\n // Configure client API, that can be called from server\n RPC.addRoute('notify', function (data) {\n console.log('Server called client route \"notify\":', data);\n return data.result;\n });\n RPC.connect();\n\n // Call stateful route\n // After you call that route, server would execute 'notify' route on the\n // client, that is registered above.\n RPC.call('test1.getEpoch').then(function (data) {\n console.log('Result for calling server route \"test1.getEpoch\": ', data);\n }, function (error) {\n alert(error);\n });\n\n // Call stateless method\n RPC.call('test2').then(function (data) {\n console.log('Result for calling server route \"test2\"', data);\n });\n</script>\n```\n\n## Versioning\n\nThis software follows [Semantic Versioning](http://semver.org/)\n\n\n",
"bugtrack_url": null,
"license": "Apache Software License",
"summary": "WSRPC is the RPC over WebSocket for aiohttp",
"version": "4.0.2",
"project_urls": {
"Homepage": "https://github.com/wsrpc/wsrpc-aiohttp"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4bccfd0fd4b3fc031f57c6db08a5cfaaa8f35bb7275d11579bf618b021210e6c",
"md5": "9ac694054eb0d38d7ae4eaffb87b99a9",
"sha256": "35d1dab2cc46f9357bc06d413751cbaa40d8e2651e2443eca453095de634936c"
},
"downloads": -1,
"filename": "wsrpc_aiohttp-4.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9ac694054eb0d38d7ae4eaffb87b99a9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7, <4",
"size": 23022,
"upload_time": "2023-08-28T11:08:51",
"upload_time_iso_8601": "2023-08-28T11:08:51.580868Z",
"url": "https://files.pythonhosted.org/packages/4b/cc/fd0fd4b3fc031f57c6db08a5cfaaa8f35bb7275d11579bf618b021210e6c/wsrpc_aiohttp-4.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4c4bd5b3ef27a9073498ce93a5002e8feaf758159093bd0a0c048dc9bf2a72c4",
"md5": "022caedf9b33ea4706987e1802ddeac4",
"sha256": "eaa1842eaa070baeb903ac6870f7d67d2ffae2767d25d5d1d7f2142555361f87"
},
"downloads": -1,
"filename": "wsrpc-aiohttp-4.0.2.tar.gz",
"has_sig": false,
"md5_digest": "022caedf9b33ea4706987e1802ddeac4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7, <4",
"size": 20689,
"upload_time": "2023-08-28T11:08:53",
"upload_time_iso_8601": "2023-08-28T11:08:53.431111Z",
"url": "https://files.pythonhosted.org/packages/4c/4b/d5b3ef27a9073498ce93a5002e8feaf758159093bd0a0c048dc9bf2a72c4/wsrpc-aiohttp-4.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-28 11:08:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "wsrpc",
"github_project": "wsrpc-aiohttp",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "wsrpc-aiohttp"
}