simple jsonrpc
Project description
simplejrpc
1. Getting Started Quickly
1.1 Install SDK
Install the SDK using pip:
pip3 install simplejrpc
Once installed, you can import and use the SDK functions in your project.
2. Service Registration
2.1 Register a Socket File
Since the SDK communicates with the backend process via a Unix Socket file (based on the JSON-RPC 2.0 protocol), you must explicitly specify the socket_path to ensure the service generates a .sock file and exposes communication capabilities.
# main.py
from simplejrpc import ServerApplication
# Specify the Unix Socket file path
socket_path = "/xxx/app.socket"
# Create the application instance
app = ServerApplication(socket_path=socket_path)
✅ Tip: Make sure the path is writable and does not conflict with other services.
2.2 Register a Configuration File (Logging System)
To enable logging, specify the path to a logger config file during initialization. You can also call app.setup_logger(config_path) after the app starts to load the logger config dynamically.
- Supported format: YAML
- If not configured, a simple logger provided by loguru is used by default.
# main.py
from simplejrpc import ServerApplication
sock_path = "/xxx/app.sock"
config_path = "/xxx/config.yaml"
# Initialize the app with logger configuration
app = ServerApplication(socket_path=sock_path, config_path=config_path)
# Alternatively, configure the logger after initialization:
# app.setup_logger(config_path)
2.3 Register Methods (Business Routes)
Registering methods exposes functions as interfaces accessible via JSON-RPC.
✅ Default Registration (Using Function Name)
If the method name is not explicitly specified, the system will use the function name by default:
from simplejrpc.response import jsonify
@app.route() # Registered as 'hello' by default
async def hello():
return jsonify(data="hello", msg="OK")
✅ Explicit Registration (Specify Method Name)
You can also specify a method name using the name parameter. It’s recommended to keep it consistent with the function name for maintainability:
from simplejrpc.response import jsonify
@app.route(name="hello") # Explicitly set method name
async def hello():
return jsonify(data="hello", msg="OK")
⚠️ Note: If
namediffers from the function name, it may cause confusion during maintenance or calls. Consistent naming is advised.
3. Making Requests
3.1 Request and Response Structure
✅ Supported Parameter Formats
The framework supports two ways of receiving request parameters:
📌 Explicit Parameter Declaration (Recommended)
Use when parameters are fixed and clearly named:
@app.route(name="hello")
async def hello(lang, action):
# Directly receive request parameters lang and action
...
✅ Advantage: Clear typing, easier validation and maintenance.
📌 Dynamic Parameter Handling (*args, **kwargs)
Use when the number of parameters is variable or needs generic processing:
@app.route(name="hello")
async def hello(*args, **kwargs):
lang = kwargs.get("lang")
action = kwargs.get("action")
...
✅ Standard Response Format
All responses should be returned using jsonify, containing code, data, and msg fields:
from simplejrpc.response import jsonify
@app.route(name="hello")
async def hello():
return jsonify(code=400, data=True, msg="Operation failed")
✅ Example Response Structure
Success Response:
{
"jsonrpc": "2.0",
"result": {
"code": 200,
"meta": {
"endpoint": null,
"close": 1
},
"data": [],
"msg": "OK"
},
"id": 1
}
Error Response:
{
"jsonrpc": "2.0",
"result": {
"code": 400,
"meta": {
"endpoint": null,
"close": 1
},
"data": null,
"msg": "expected value ['start', 'stop']"
},
"id": 1
}
3.2 Start the Service
Example server code:
# main.py
import asyncio
from simplejrpc import ServerApplication
from simplejrpc.response import jsonify
socket_path = "/xxx/app.socket"
app = ServerApplication(socket_path)
@app.route(name="hello")
async def hello():
return jsonify(data="hello", msg="OK")
if __name__ == "__main__":
asyncio.run(app.run())
Start the service:
$ python3 main.py
3.3 Call Interface (Client Test)
Use the SDK's Request class for testing:
from simplejrpc import Request
# Must match the socket path used by the server
socket_path = "/xxx/app.sock"
def test_hello():
method = "hello"
params = {
"lang": "zh-CN",
"action": "start"
}
request = Request(socket_path)
result = request.send_request(method, params)
print("[recv] >", result)
4. Making Requests
4.1 Form Validation
The SDK integrates wtforms to provide a simple yet powerful validation system with support for custom validators.
✅ Example: Define and Use a Form Class
from simplejrpc.schemas import BaseForm, StrRangeValidator, simple
from simplejrpc.response import jsonify
# Custom form class, restricts 'action' to "start" or "stop"
class TestForm(BaseForm):
action = simple.StringField(
validators=[StrRangeValidator(allows=["start", "stop"])]
)
# Specify socket path and register app
socket_path = "/xxx/app.socket"
app = ServerApplication(socket_path)
# Specify 'form' to trigger validation automatically
@app.route(name="hello", form=TestForm)
async def hello(lang, action):
return jsonify(data=[1, 2, 3], msg="OK")
✅ Custom Validators
You can create custom validation logic by extending BaseValidator.
A custom validator class must inherit from
BaseValidatorand implement thevalidator(form, field)method. Only two parameters are accepted: the form instance and the field instance.
from simplejrpc import BaseValidator
class TestValidator(BaseValidator):
def validator(self, form, field):
# Custom logic: value must be uppercase
if field.data and not field.data.isupper():
raise ValueError("Field must be uppercase")
Use the custom validator in your form:
class TestForm(BaseForm):
action = simple.StringField(
validators=[
StrRangeValidator(allows=["start", "stop"]),
TestValidator()
]
)
4.2 Exception Handling
The framework includes a built-in exception handling system. Just raise exceptions, and the framework will format them into standard JSON-RPC error responses.
✅ Example
from simplejrpc.exceptions import RPCException
@app.route(name="hello", form=TestForm)
async def hello(lang, action):
raise RPCException("Test error") # Automatically caught and formatted
✅ Custom Exception Classes
The framework provides a base exception class that can be extended:
class UnauthorizedError(RPCException):
"""Unauthorized"""
class ValidationError(RPCException):
"""Validation failed"""
class FileNotFoundError(RPCException):
"""File not found"""
class ValueError(RPCException):
"""Value error"""
class RuntimeError(RPCException):
"""Runtime error"""
4.3 Internationalization (i18n)
The SDK supports multilingual output using .ini files, driven by the lang parameter in each request.
✅ Initialize Language Configuration
Your project root should include an i18n/ directory:
project/
├── main.py
└── i18n/
├── zh-CN.ini
└── en.ini
Initialize with GI18n():
GI18n(i18n_dir="i18n", lang="zh-CN")
⚠️ Each request should include a
langparameter, which the framework uses to set the language.
✅ Example 1: Basic Translation
en.ini
TEST_I18N = "test"
Python usage:
from simplejrpc import i18n
print(i18n.translate("TEST_I18N")) # Output: test
✅ Example 2: Placeholder Translation (Parameterized)
en.ini
TEST_I18N = "test{}"
Python usage:
from simplejrpc import i18n
print(i18n.translate_ctx("TEST_I18N", "i18n")) # Output: testi18n
✅ Supported Languages
| Language Code | Description | Region/Note |
|---|---|---|
en |
English | Default |
zh-CN |
Simplified Chinese | Mainland China |
zh-TW |
Traditional Chinese | Taiwan/Hong Kong |
ja |
Japanese | Japan |
ru |
Russian | Russia |
4.4 Middleware Support
The framework supports middleware for handling common logic before and after request processing, such as logging, authentication, or performance analysis.
✅ Example Usage
from simplejrpc import ServerApplication
from simplejrpc.interfaces import RPCMiddleware
class CustomMiddleware(RPCMiddleware):
def process_request(self, request, context):
print("[Before] Incoming request:", request)
return request
def process_response(self, response, context):
print("[After] Outgoing response:", response)
return response
# Register middleware
app = ServerApplication("/xxx/app.sock")
app.middleware(CustomMiddleware())
Would you like this translated version exported into a PDF or Markdown file?
Feedback
Open a ticket / fork the project on Gitee.
Open a ticket / fork the project on Github.
Here is the fully translated version of your documentation from Chinese to English:
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simplejrpc-2.2.2.tar.gz.
File metadata
- Download URL: simplejrpc-2.2.2.tar.gz
- Upload date:
- Size: 53.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0735bb05a5296dbed6bb1f57b11762937e0f538916aab9d8a7101c8aa0862e46
|
|
| MD5 |
e30f3e672235f7daf6ef8566d4080f72
|
|
| BLAKE2b-256 |
883764794d22363e3dce6ddf61ab1a2ef66e54dc2ade68a50f9b429883491a86
|
File details
Details for the file simplejrpc-2.2.2-py2.py3-none-any.whl.
File metadata
- Download URL: simplejrpc-2.2.2-py2.py3-none-any.whl
- Upload date:
- Size: 53.9 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
43b812a4e204b27ada9195d346dd49050c37504be3253285c49c65231170a3a6
|
|
| MD5 |
e498c86cf1e1cc2a9a0c8fe16194f331
|
|
| BLAKE2b-256 |
e60853387da26cf95edb90af214a33079827ad8c410a83db5ed658ebc4a5c666
|