Zero is a RPC framework to build fast and high performance Python microservices
Project description
Zero is a simple RPC like framework to build fast and high performance Python microservices or distributed servers
Features:
- Zero provides faster communication (see benchmarks) between the microservices using zeromq under the hood.
- Zero uses messages for communication and traditional client-server or request-reply pattern is supported.
- Support for both Async and sync.
- The base server (ZeroServer) utilizes all cpu cores.
- Code generation! See example 👇
Philosophy behind Zero:
- Zero learning curve: The learning curve is tends to zero. You just add your functions and spin up a server, literally that's it! The framework hides the complexity of messaging pattern that enables faster communication.
- ZeroMQ: An awesome messaging library enables the power of Zero.
Let's get started!
Getting started 🚀
Ensure Python 3.8+
pip install zeroapi
For Windows, tornado needs to be installed separately (for async operations). It's not included with zeroapi
because for linux and mac-os, tornado is not needed as they have their own event loops.
- Create a
server.py
from zero import ZeroServer
def echo(msg: str) -> str:
return msg
async def hello_world() -> str:
return "hello world"
if __name__ == "__main__":
app = ZeroServer(port=5559)
app.register_rpc(echo)
app.register_rpc(hello_world)
app.run()
Please note that server RPC methods are type hinted. Type hint is must in Zero server.
See the method type async or sync, doesn't matter. 😃
- Run it
python -m server
- Call the rpc methods
from zero import ZeroClient
zero_client = ZeroClient("localhost", 5559)
def echo():
resp = zero_client.call("echo", "Hi there!")
print(resp)
def hello():
resp = zero_client.call("hello_world", None)
print(resp)
if __name__ == "__main__":
echo()
hello()
Or using async client -
import asyncio
from zero import AsyncZeroClient
zero_client = AsyncZeroClient("localhost", 5559)
async def echo():
resp = await zero_client.call("echo", "Hi there!")
print(resp)
async def hello():
resp = await zero_client.call("hello_world", None)
print(resp)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(echo())
loop.run_until_complete(hello())
Code Generation! 🙌
You can also use our code generation tool to generate Python client code!
After running the server, like above, you can call the server to get the client code.
python -m zero.generate_client --host localhost --port 5559 --overwrite-dir ./my_client
It will generate client like this -
import typing # remove this if not needed
from typing import List, Dict, Union, Optional, Tuple # remove this if not needed
from zero import ZeroClient
zero_client = ZeroClient("localhost", 5559)
class RpcClient:
def __init__(self, zero_client: ZeroClient):
self._zero_client = zero_client
def echo(self, msg: str) -> str:
return self._zero_client.call("echo", msg)
def hello_world(self, msg: str) -> str:
return self._zero_client.call("hello_world", msg)
You can just use this -
from my_client import RpcClient, zero_client
client = RpcClient(zero_client)
if __name__ == "__main__":
client.echo("Hi there!")
client.hello_world(None)
Using zero.generate_client
you can generate client code for even remote servers using the --host
and --port
options. You don't need access to the code 😃
Important notes 📝
ZeroServer
should always be run underif __name__ == "__main__":
, as it uses multiprocessing.- The methods which are under
register_rpc()
inZeroServer
should have type hinting, likedef echo(msg: str):
Let's do some benchmarking 🤘
Zero is talking about inter service communication. In most real life scenarios, we need to call another microservice.
So we will be testing a gateway calling another server for some data. Check the benchmark/dockerize folder for details.
There are two endpoints in every tests,
/hello
: Just call for a hello world response 😅/order
: Save a Order object in redis
Compare the results! 👇
Benchmarks 🏆
11th Gen Intel® Core™ i7-11800H @ 2.30GHz, 8 cores, 16 threads, 16GB RAM (Docker in Ubuntu 22.04.2 LTS)
(Sorted alphabetically)
Framework | "hello world" (req/s) | 99% latency (ms) | redis save (req/s) | 99% latency (ms) |
---|---|---|---|---|
aiohttp | 14391.38 | 10.96 | 9470.74 | 12.94 |
aiozmq | 15121.86 | 9.42 | 5904.84 | 21.57 |
fastApi | 9590.96 | 18.31 | 6669.81 | 24.41 |
sanic | 18790.49 | 8.69 | 12259.29 | 13.52 |
zero(sync) | 24805.61 | 4.57 | 16498.83 | 7.80 |
Todo list 📃
- Add pydantic support
- Code generation for pydantic models
- Improve error handling
- Fault tolerance
Contribution
Contributors are welcomed 🙏
Please leave a star ⭐ if you like Zero!
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 zeroapi-0.3.4.tar.gz
.
File metadata
- Download URL: zeroapi-0.3.4.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 16d39b6b0c7763cc765515765583c9d7825f8d13b6ad8dcec89c3531b0df1270 |
|
MD5 | a469d12305397a89e1a3631f394902c0 |
|
BLAKE2b-256 | acdab49c9c8487b67d6f5964652296c961491f03ef7e1dba6da132073c004d38 |
File details
Details for the file zeroapi-0.3.4-py3-none-any.whl
.
File metadata
- Download URL: zeroapi-0.3.4-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a91b41c1d341c9abd3a74ab81790cdbb156c9664a884d800f93d24e87463a5ac |
|
MD5 | 188e3dda4ce42221748fb91f6827dd53 |
|
BLAKE2b-256 | f6dd463064ea9f76910d6e17f70953f8cdfa83eb8c0644426f93d1761506e425 |