0
# Core JSON-RPC Protocol
1
2
Complete implementation of JSON-RPC 1.0 and 2.0 protocols providing automatic version detection, request parsing, response generation, and comprehensive error handling. The protocol layer is transport-agnostic, allowing integration with any communication mechanism.
3
4
## Capabilities
5
6
### Request Processing
7
8
The main entry point for processing JSON-RPC requests, automatically detecting protocol version and handling both single and batch requests.
9
10
```python { .api }
11
class JSONRPCResponseManager:
12
@classmethod
13
def handle(cls, request_str: str, dispatcher: dict, context: dict = None):
14
"""
15
Handle JSON-RPC request string and return response.
16
17
Parameters:
18
- request_str: JSON string containing the request
19
- dispatcher: Dictionary mapping method names to callable functions
20
- context: Optional context dictionary passed to methods that request it
21
22
Returns:
23
Response object (JSONRPC10Response, JSONRPC20Response, JSONRPC20BatchResponse, or None for notifications)
24
"""
25
26
@classmethod
27
def handle_request(cls, request, dispatcher: dict, context: dict = None):
28
"""
29
Handle parsed request object directly.
30
31
Parameters:
32
- request: Parsed request object (JSONRPC10Request, JSONRPC20Request, or JSONRPC20BatchRequest)
33
- dispatcher: Dictionary mapping method names to callable functions
34
- context: Optional context dictionary passed to methods that request it
35
36
Returns:
37
Response object or None for notifications
38
"""
39
```
40
41
### Protocol Version Detection
42
43
Automatic detection between JSON-RPC 1.0 and 2.0 based on request format, with fallback handling for invalid requests.
44
45
```python { .api }
46
class JSONRPCRequest:
47
@classmethod
48
def from_json(cls, json_str: str):
49
"""
50
Parse JSON string and create appropriate request object.
51
52
Parameters:
53
- json_str: JSON string to parse
54
55
Returns:
56
JSONRPC10Request or JSONRPC20Request/JSONRPC20BatchRequest based on format
57
58
Raises:
59
JSONRPCInvalidRequestException: If request format is invalid
60
"""
61
62
@classmethod
63
def from_data(cls, data: dict):
64
"""
65
Create request object from parsed data.
66
67
Parameters:
68
- data: Dictionary or list containing request data
69
70
Returns:
71
JSONRPC10Request or JSONRPC20Request/JSONRPC20BatchRequest
72
"""
73
```
74
75
### Response Class Mapping
76
77
Internal mapping system that selects appropriate response classes based on protocol version.
78
79
```python { .api }
80
# Response class mapping used internally
81
RESPONSE_CLASS_MAP = {
82
"1.0": JSONRPC10Response,
83
"2.0": JSONRPC20Response,
84
}
85
```
86
87
## Usage Examples
88
89
### Basic Request Handling
90
91
```python
92
from jsonrpc import JSONRPCResponseManager, dispatcher
93
94
# Register methods
95
@dispatcher.add_method
96
def ping():
97
return "pong"
98
99
@dispatcher.add_method
100
def add(a, b):
101
return a + b
102
103
# Handle JSON-RPC 2.0 request
104
request = '{"jsonrpc": "2.0", "method": "add", "params": [1, 2], "id": 1}'
105
response = JSONRPCResponseManager.handle(request, dispatcher)
106
print(response.json)
107
# {"jsonrpc": "2.0", "result": 3, "id": 1}
108
109
# Handle JSON-RPC 1.0 request (no "jsonrpc" field)
110
request = '{"method": "ping", "params": [], "id": 1}'
111
response = JSONRPCResponseManager.handle(request, dispatcher)
112
print(response.json)
113
# {"result": "pong", "id": 1}
114
```
115
116
### Batch Request Processing
117
118
```python
119
# Handle batch request (JSON-RPC 2.0 only)
120
batch_request = '''[
121
{"jsonrpc": "2.0", "method": "add", "params": [1, 2], "id": "1"},
122
{"jsonrpc": "2.0", "method": "ping", "id": "2"},
123
{"jsonrpc": "2.0", "method": "add", "params": [5, 7], "id": "3"}
124
]'''
125
126
response = JSONRPCResponseManager.handle(batch_request, dispatcher)
127
print(response.json)
128
# [
129
# {"jsonrpc": "2.0", "result": 3, "id": "1"},
130
# {"jsonrpc": "2.0", "result": "pong", "id": "2"},
131
# {"jsonrpc": "2.0", "result": 12, "id": "3"}
132
# ]
133
```
134
135
### Context Injection
136
137
```python
138
from jsonrpc import Dispatcher
139
140
# Create dispatcher with context-aware method
141
dispatcher = Dispatcher()
142
143
@dispatcher.add_method(context_arg="ctx")
144
def get_user_info(user_id, ctx):
145
# Context can contain request information, authentication, etc.
146
request_id = ctx.get("request", {}).get("_id")
147
return {"user_id": user_id, "processed_by_request": request_id}
148
149
# Handle request with context
150
context = {"user": "admin", "timestamp": "2023-01-01"}
151
request = '{"jsonrpc": "2.0", "method": "get_user_info", "params": [123], "id": 1}'
152
response = JSONRPCResponseManager.handle(request, dispatcher, context)
153
```
154
155
### Error Handling
156
157
```python
158
from jsonrpc.exceptions import JSONRPCDispatchException, JSONRPCMethodNotFound
159
160
@dispatcher.add_method
161
def divide(a, b):
162
if b == 0:
163
raise JSONRPCDispatchException(
164
code=-32602,
165
message="Division by zero",
166
data={"dividend": a, "divisor": b}
167
)
168
return a / b
169
170
# Error responses are automatically formatted
171
request = '{"jsonrpc": "2.0", "method": "divide", "params": [10, 0], "id": 1}'
172
response = JSONRPCResponseManager.handle(request, dispatcher)
173
print(response.json)
174
# {"jsonrpc": "2.0", "error": {"code": -32602, "message": "Division by zero", "data": {"dividend": 10, "divisor": 0}}, "id": 1}
175
176
# Method not found
177
request = '{"jsonrpc": "2.0", "method": "nonexistent", "id": 1}'
178
response = JSONRPCResponseManager.handle(request, dispatcher)
179
print(response.json)
180
# {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": 1}
181
```