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:
Metadata
Release files for simplejrpc 2.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| simplejrpc-2.2.9.tar.gz | 54.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| simplejrpc-2.2.9-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 109.8 kB
Release files / simplejrpc-2.2.9.tar.gz
| Download URL | simplejrpc-2.2.9.tar.gz |
|---|---|
| Size | 54.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43a86188ff5e51df614b72c6c7b4ff4e6c393c3c43db744b21e50858175d4d9e
|
|
BLAKE2b-256 checksum How to use checksums |
79f715187eb2f8dbf5b58c9a37ba6d9953491f440d2bd584473d31cb85f70515
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|
Release files / simplejrpc-2.2.9-py2.py3-none-any.whl
| Download URL | simplejrpc-2.2.9-py2.py3-none-any.whl |
|---|---|
| Size | 55.4 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
541007d199447aa380304d94855e721bbf60bf500cb15b2777f3741d22a5d95d
|
|
BLAKE2b-256 checksum How to use checksums |
c9225923ffb6431cf1782a391efa77cda142efc95cb1a585fe07530656a01505
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|