WSRPC aiohttp
Two-way remote procedure calls over WebSockets for aiohttp. A Python or JavaScript client can call the server, and the server can call the client over the same connection.
- Expose functions or stateful route classes.
- Run asynchronous handlers or synchronous handlers in a thread pool.
- Make concurrent calls and receive results independently.
- Receive remote errors as exceptions.
- Observe connection and call lifecycles with asynchronous signals.
Python 3.10–3.15 is tested, including free-threaded 3.13–3.15. See the documentation for routes, authentication, callbacks, signals and API reference.
Install
pip install wsrpc-aiohttp
The Python package includes the JavaScript client. For a standalone frontend, it is also available on npm:
npm install @wsrpc/client
Start a server
Save this as server.py and run python server.py:
from aiohttp import web
from wsrpc_aiohttp import STATIC_DIR, WebSocketAsync
class Socket(WebSocketAsync):
pass
async def echo(socket: Socket, *, message: str) -> str:
return message
def create_app() -> web.Application:
Socket.add_route("echo", echo)
app = web.Application()
app.router.add_get("/ws/", Socket)
app.router.add_static("/js/", STATIC_DIR)
return app
if __name__ == "__main__":
web.run_app(create_app(), host="127.0.0.1", port=8000)
Call it from Python
Save this as client.py and run it while the server is running:
import asyncio
from wsrpc_aiohttp import WSRPCClient
async def main() -> None:
async with WSRPCClient("http://127.0.0.1:8000/ws/") as client:
result = await client.proxy.echo(message="Hello from Python")
print(result)
if __name__ == "__main__":
asyncio.run(main())
Calls use keyword arguments. await client.call("echo", message="Hello") is equivalent to await client.proxy.echo(message="Hello"). The client context manager connects and closes the connection and its HTTP session.
The following self-contained test starts an ephemeral server and exercises the same API:
import asyncio
from aiohttp import web
from aiohttp.test_utils import TestServer
from wsrpc_aiohttp import WebSocketAsync, WSRPCClient
async def round_trip() -> None:
class Socket(WebSocketAsync):
pass
Socket.add_route("echo", lambda socket, *, message: message)
app = web.Application()
app.router.add_get("/ws/", Socket)
async with TestServer(app) as server:
async with WSRPCClient(str(server.make_url("/ws/"))) as client:
assert await client.proxy.echo(message="Hello") == "Hello"
asyncio.run(round_trip())
Call it from a browser
For a page served by the same application, load the bundled script from /js/ and call the same method:
<script src="/js/wsrpc.min.js"></script>
<script>
const scheme = window.location.protocol === "https:" ? "wss:" : "ws:";
const url = scheme + "//" + window.location.host + "/ws/";
const rpc = new WSRPC(url);
rpc.connect();
async function echo() {
try {
const result = await rpc.call("echo", {message: "Hello from JavaScript"});
console.log(result);
} catch (error) {
console.error(error);
}
}
echo();
</script>
The example selects wss:// on HTTPS pages and ws:// on HTTP pages. A complete browser example is in the quick start.
JSON codecs
Messages use the standard library json module. To use another codec, pass loads and dumps to WSRPCClient or WebSocketAsync.configure(). The dumps callback must return str and accept the default serializer keyword argument. The base installation works on free-threaded Python without a native JSON extension.
Development
Building distributions from this repository requires Git, Node.js >=22 and npm: the browser client is built from current wsrpc-ts sources. Installing a wheel or building from an sdist does not require Node.js. See client build details for revision selection and provenance.
Install uv, clone the repository, then run:
uv sync --locked
uv run --locked pytask
All development dependencies are in dev. Pytask runs linting, type checking, tests (including marked README examples) and package builds. Select a task with -k:
uv run --locked pytask -k tests
uv run --locked pytask -k lint
uv run --locked pytask -k typing
uv run --locked pytask -k test_readme
uv run --locked pytask -k build
Documentation and its runnable examples are maintained in wsrpc/docs and published at docs.wsrpc.org. See the development guide for the test matrix and release process.
License and versioning
Licensed under Apache-2.0. The bundled JavaScript client has its own MIT license. Releases follow Semantic Versioning.
Metadata
Release files for wsrpc-aiohttp 4.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| wsrpc_aiohttp-4.1.1.tar.gz | 48.6 kB | With provenance | Details for wsrpc_aiohttp-4.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| wsrpc_aiohttp-4.1.1-py3-none-any.whl | Python 3 | none | any | Details for wsrpc_aiohttp-4.1.1-py3-none-any.whl |
Total release size: 99.0 kB
Release files / wsrpc_aiohttp-4.1.1.tar.gz
| Download URL | wsrpc_aiohttp-4.1.1.tar.gz |
|---|---|
| Size | 48.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5d74a3a9d4ed0c849d0aeea26655fbe04f0dbccf99938a95d6949ba7d4ce19a5
|
|
BLAKE2b-256 checksum How to use checksums |
a40ca293f148a92cd6655c4a44481e212581233e8d761cc3f0a53e422de46413
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / wsrpc_aiohttp-4.1.1-py3-none-any.whl
| Download URL | wsrpc_aiohttp-4.1.1-py3-none-any.whl |
|---|---|
| Size | 50.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0cf223efd41c48300854e9861bd72ab9b51f9cf3e287b01dedd1a30b11a2d373
|
|
BLAKE2b-256 checksum How to use checksums |
e6fadcac9b691a8e2232aca1d6aaeb3dc458d01094b5e359813d8f0268457ff2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for wsrpc-aiohttp 4.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for wsrpc_aiohttp-4.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.