A modern `Json-Rpc/Bson-Rpc` implementation, compatible with `Json-Rpc Ast` and `Json-Rpc 2.0` and `Json-Rpc X`, supports multiple network protocols and backend frameworks and supports bidirectional calls.
Project description
Lacia
A modern Json-Rpc/Bson-Rpc
implementation, compatible with Json-Rpc Ast
and Json-Rpc 2.0
and Json-Rpc X
, supports multiple network protocols and backend frameworks and supports bidirectional calls.
人间总有一两风,填我十万八千梦
安装
pip install lacia>=0.2
pdm add lacia>=0.2
特性
- 跨语言
-
Python3
-
JavaScript/TypeScript
-
Golang
-
C/C++
-
Java
-
Rust
-
- 多种网络协议支持
-
HTTP
-
WebSocket
-
自定义
-
- 多种Runtime支持
- 兼容 Json-Rpc Ast 规范
- 兼容 Json-Rpc 2.0 规范
- 兼容 Json-Rpc X 规范
- 支持完备的链式调用
- 支持嵌套调用
- 支持双向调用 (StoC, CtoS, CtoC)
- 双向流式传输
- 支持 BSON
- IDE 支持
- 分布式Server
使用
入门
Server 端
from lacia.core.core import JsonRpc
from lacia.network.server.aioserver import AioServer, mount_app
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
rpc = JsonRpc(
name="client_test",
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
ping = ProxyObj(rpc).ping
assert await ping("hello") == "pong hello"
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
链式调用
Server 端
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
rpc = JsonRpc(
name="client_test",
)
class Test:
def __init__(self, a, b) -> None:
self.a = a
self.b = b
def output(self, name):
return f"hello: {name}, a: {self.a}, b: {self.b}"
namespace = {
"Test": Test
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
rpc = JsonRpc(
name="client_test",
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
Test = ProxyObj(rpc).Test
assert await Test(1, 2).output("world") == "hello: world, a: 1, b: 2"
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
反向调用
Server 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.server.aioserver import AioServer, mount_app
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
async def reverse_call(name: str):
res = await ProxyObj(rpc, name=name).ping(name)
return res
rpc.add_namespace({
"reverse_call": reverse_call,
})
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
from pprint import pprint
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(
name="client_test",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
proxy1 = ProxyObj(rpc).reverse_call
assert await proxy1("hello") == "pong hello"
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
流式调用
Server 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.server.aioserver import AioServer, mount_app
async def test_async_iter(n: int):
for i in range(n):
await asyncio.sleep(1)
yield i
namespace = {
"test_async_iter": test_async_iter,
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
from pprint import pprint
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(
name="client_test",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
proxy3 = ProxyObj(rpc).test_async_iter
async for i in proxy3(3):
print(i)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
反向流式调用
Server 端
import asyncio
from lacia.core.core import JsonRpc, Context
from lacia.core.proxy import ProxyObj
from lacia.network.server.aioserver import AioServer, mount_app
async def test_async_iter(n: int):
name = Context.name.get()
obj = ProxyObj(Context.rpc.get(), name)
async for i in obj.test_async_iter(n):
yield i
namespace = {
"test_async_iter": test_async_iter,
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
async def test_async_iter(n: int):
for i in range(n):
await asyncio.sleep(1)
yield i
namespace = {
"test_async_iter": test_async_iter,
}
rpc = JsonRpc(
name="client_test",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
proxy = ProxyObj(rpc).test_async_iter
async for i in proxy(3):
print(i)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
嵌套调用
Server 端
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.server.aioserver import AioServer, mount_app
class Test:
def __init__(self, a, b) -> None:
self.a = a
self.b = b
def output(self, name):
return f"hello: {name}"
def class_sum(obj: Test):
return obj.a + obj.b
namespace = {
"class_sum": class_sum,
"Test": Test,
}
rpc = JsonRpc(name = "server_test", namespace=namespace)
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端
from pprint import pprint
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(
name="client_test",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
proxy1 = ProxyObj(rpc).Test(1, b=2)
proxy2 = ProxyObj(rpc).class_sum(proxy1)
assert await proxy2 == 3
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Client to Client
Server 端
import asyncio
from lacia.core.core import JsonRpc, Context
from lacia.core.proxy import ProxyObj
from lacia.network.server.aioserver import AioServer
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(name = "server_test")
if __name__ == "__main__":
from aiohttp import web
app = web.Application()
mount_app(app=app, server=server, rpc=rpc, path="/ws")
web.run_app(app, host="localhost", port=8080)
Client 端 A
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
async def test_async_iter(n: int):
for i in range(n):
await asyncio.sleep(1)
yield i
namespace = {
"ping": lambda x: f"pong {x}",
"test_async_iter": test_async_iter,
}
rpc = JsonRpc(
name="client_test_A",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.run_forever()
Client 端 B
import asyncio
from lacia.core.core import JsonRpc
from lacia.core.proxy import ProxyObj
from lacia.network.client.aioclient import AioClient
namespace = {
"ping": lambda x: f"pong {x}",
}
rpc = JsonRpc(
name="client_test_B",
namespace=namespace
)
async def main():
client = AioClient(path="/ws")
await rpc.run_client(client)
c_obj = ProxyObj(rpc, "client_test_A")
s_obj = ProxyObj(rpc)
async for i in c_obj.test_async_iter(10):
print(i)
print(await s_obj.ping(c_obj.ping("hello")))
print(await c_obj.ping(s_obj.ping("hello")))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file lacia-0.2.0.tar.gz
.
File metadata
- Download URL: lacia-0.2.0.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.15.4 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 91ae5f0bbf14dd8cd87f97e31d3732372f6c18623c9be4dcc8e13d7b92e538a8 |
|
MD5 | 0d70f4c28a1c2205734208341638f668 |
|
BLAKE2b-256 | cb9ad8f1f2fb917a9c3cb1f863d00ae84aa2053021d6f28c8ed87cc2ec4931e9 |
File details
Details for the file lacia-0.2.0-py3-none-any.whl
.
File metadata
- Download URL: lacia-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.15.4 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0446e42b931708f2bb179212661fb04248e3e0cd96666c8aab4398530057805b |
|
MD5 | 609c68b27d8a741ce3a2a00435458de8 |
|
BLAKE2b-256 | fdd9afaf524993d00436a464a1aee3ba799dae2454807b6428802e759cf986c3 |