0
# Backend Integrations
1
2
Ready-to-use integrations for Django and Flask frameworks providing HTTP endpoints, URL routing, method mapping views, and request handling. These backends handle HTTP transport while leveraging the core JSON-RPC protocol implementation.
3
4
## Capabilities
5
6
### Django Backend
7
8
Complete Django integration with URL patterns, views, and optional method mapping interface.
9
10
```python { .api }
11
from jsonrpc.backend.django import JSONRPCAPI
12
13
class JSONRPCAPI:
14
def __init__(self, dispatcher = None):
15
"""
16
Initialize Django JSON-RPC API.
17
18
Parameters:
19
- dispatcher: Optional Dispatcher instance (creates new if None)
20
"""
21
22
@property
23
def urls(self):
24
"""
25
Get URL patterns for Django.
26
27
Returns:
28
List of URL patterns for Django routing
29
"""
30
31
def jsonrpc(self, request):
32
"""
33
Django view for JSON-RPC endpoint.
34
35
Parameters:
36
- request: Django HttpRequest object
37
38
Returns:
39
HttpResponse with JSON-RPC response
40
"""
41
42
def jsonrpc_map(self, request):
43
"""
44
Django view for method mapping display.
45
46
Parameters:
47
- request: Django HttpRequest object
48
49
Returns:
50
HttpResponse with HTML method list
51
"""
52
53
# Pre-created API instance
54
api: JSONRPCAPI
55
56
# Response serialization function
57
def response_serialize(obj) -> str:
58
"""Serialize response data with datetime/decimal support."""
59
```
60
61
### Flask Backend
62
63
Complete Flask integration with Blueprint support, views, and flexible configuration.
64
65
```python { .api }
66
from jsonrpc.backend.flask import JSONRPCAPI
67
68
class JSONRPCAPI:
69
def __init__(self, dispatcher = None, check_content_type: bool = True):
70
"""
71
Initialize Flask JSON-RPC API.
72
73
Parameters:
74
- dispatcher: Optional Dispatcher instance (creates new if None)
75
- check_content_type: Whether to require "application/json" content-type
76
"""
77
78
def as_blueprint(self, name: str = None):
79
"""
80
Create Flask Blueprint with JSON-RPC routes.
81
82
Parameters:
83
- name: Blueprint name (generates UUID if None)
84
85
Returns:
86
Flask Blueprint with routes configured
87
"""
88
89
def as_view(self):
90
"""
91
Get view function for manual route registration.
92
93
Returns:
94
View function for Flask route
95
"""
96
97
def jsonrpc(self):
98
"""
99
Flask view for JSON-RPC endpoint.
100
101
Returns:
102
Flask Response with JSON-RPC response
103
"""
104
105
def jsonrpc_map(self):
106
"""
107
Flask view for method mapping display.
108
109
Returns:
110
Flask Response with HTML method list
111
"""
112
113
# Pre-created API instance
114
api: JSONRPCAPI
115
```
116
117
## Usage Examples
118
119
### Django Integration
120
121
```python
122
# django_project/views.py
123
from jsonrpc.backend.django import api
124
125
# Add methods to the API
126
@api.dispatcher.add_method
127
def hello(name):
128
return f"Hello, {name}!"
129
130
@api.dispatcher.add_method
131
def add(a, b):
132
return a + b
133
134
# django_project/urls.py
135
from django.urls import path, include
136
from jsonrpc.backend.django import api
137
138
urlpatterns = [
139
path('admin/', admin.site.urls),
140
path('api/', include(api.urls)), # Includes both endpoint and map
141
]
142
143
# Alternative: Manual URL configuration
144
from django.urls import path
145
from jsonrpc.backend.django import api
146
147
urlpatterns = [
148
path('jsonrpc/', api.jsonrpc, name='jsonrpc_endpoint'),
149
path('jsonrpc/map/', api.jsonrpc_map, name='jsonrpc_map'),
150
]
151
```
152
153
### Custom Django API
154
155
```python
156
from jsonrpc.backend.django import JSONRPCAPI
157
from jsonrpc import Dispatcher
158
159
# Create custom dispatcher with methods
160
class MathService:
161
def add(self, a, b):
162
return a + b
163
164
def multiply(self, a, b):
165
return a * b
166
167
math_dispatcher = Dispatcher()
168
math_dispatcher.add_object(MathService())
169
170
# Create custom API instance
171
math_api = JSONRPCAPI(dispatcher=math_dispatcher)
172
173
# In urls.py
174
from django.urls import path, include
175
176
urlpatterns = [
177
path('math/', include(math_api.urls)),
178
]
179
180
# Usage: POST to /math/ with JSON-RPC request
181
# {"jsonrpc": "2.0", "method": "add", "params": [5, 3], "id": 1}
182
```
183
184
### Django with Context Injection
185
186
```python
187
from jsonrpc.backend.django import api
188
from django.contrib.auth.decorators import login_required
189
from django.views.decorators.csrf import csrf_exempt
190
from django.http import HttpResponse
191
import json
192
193
# Method that uses Django request context
194
@api.dispatcher.add_method
195
def get_user_info(request):
196
"""This method automatically receives the Django request object."""
197
return {
198
"user": request.user.username if request.user.is_authenticated else "anonymous",
199
"method": request.method,
200
"path": request.path,
201
"is_ajax": request.headers.get('X-Requested-With') == 'XMLHttpRequest'
202
}
203
204
@api.dispatcher.add_method
205
def protected_method(secret_data, request):
206
"""Method that checks authentication via Django request."""
207
if not request.user.is_authenticated:
208
from jsonrpc.exceptions import JSONRPCDispatchException
209
raise JSONRPCDispatchException(
210
code=-32001,
211
message="Authentication required"
212
)
213
214
return {"data": secret_data, "user": request.user.username}
215
216
# Custom view with authentication
217
@csrf_exempt
218
@login_required
219
def authenticated_jsonrpc(request):
220
return api.jsonrpc(request)
221
222
# In urls.py
223
urlpatterns = [
224
path('api/', include(api.urls)), # Public API
225
path('secure-api/', authenticated_jsonrpc), # Authenticated API
226
]
227
```
228
229
### Flask Integration
230
231
```python
232
# app.py
233
from flask import Flask
234
from jsonrpc.backend.flask import api
235
236
app = Flask(__name__)
237
238
# Add methods to the API
239
@api.dispatcher.add_method
240
def hello(name):
241
return f"Hello, {name}!"
242
243
@api.dispatcher.add_method
244
def add(a, b):
245
return a + b
246
247
# Method 1: Using Blueprint
248
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
249
250
# Method 2: Manual route registration
251
# app.add_url_rule('/api', view_func=api.as_view(), methods=['POST'])
252
253
if __name__ == '__main__':
254
app.run(debug=True)
255
256
# Usage:
257
# POST to /api/ with JSON-RPC request
258
# GET /api/map to see available methods
259
```
260
261
### Custom Flask API
262
263
```python
264
from flask import Flask
265
from jsonrpc.backend.flask import JSONRPCAPI
266
from jsonrpc import Dispatcher
267
268
app = Flask(__name__)
269
270
# Create custom dispatcher
271
user_dispatcher = Dispatcher()
272
273
@user_dispatcher.add_method
274
def get_user(user_id):
275
return {"id": user_id, "name": f"User {user_id}"}
276
277
@user_dispatcher.add_method
278
def create_user(name, email):
279
return {"id": 123, "name": name, "email": email, "created": True}
280
281
# Create custom API
282
user_api = JSONRPCAPI(dispatcher=user_dispatcher, check_content_type=False)
283
284
# Register with different prefixes
285
app.register_blueprint(user_api.as_blueprint('user_api'), url_prefix='/users')
286
287
# Multiple APIs
288
admin_dispatcher = Dispatcher()
289
admin_dispatcher["admin.status"] = lambda: {"status": "running", "version": "1.0"}
290
291
admin_api = JSONRPCAPI(dispatcher=admin_dispatcher)
292
app.register_blueprint(admin_api.as_blueprint('admin_api'), url_prefix='/admin')
293
294
if __name__ == '__main__':
295
app.run()
296
```
297
298
### Flask with Error Handling
299
300
```python
301
from flask import Flask, request
302
from jsonrpc.backend.flask import JSONRPCAPI
303
from jsonrpc.exceptions import JSONRPCDispatchException
304
import logging
305
306
app = Flask(__name__)
307
logging.basicConfig(level=logging.INFO)
308
309
# Custom API with error handling
310
api = JSONRPCAPI()
311
312
@api.dispatcher.add_method
313
def divide(a, b):
314
if b == 0:
315
raise JSONRPCDispatchException(
316
code=-32602,
317
message="Division by zero",
318
data={"dividend": a, "divisor": b}
319
)
320
return a / b
321
322
@api.dispatcher.add_method
323
def get_client_info():
324
"""Return information about the client making the request."""
325
return {
326
"remote_addr": request.remote_addr,
327
"user_agent": request.headers.get('User-Agent'),
328
"content_type": request.content_type,
329
"content_length": request.content_length
330
}
331
332
# Custom error handler
333
@app.errorhandler(500)
334
def handle_server_error(error):
335
app.logger.error(f"Server error: {error}")
336
return {"error": "Internal server error"}, 500
337
338
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
339
340
if __name__ == '__main__':
341
app.run(debug=True)
342
```
343
344
### Content Type Handling
345
346
```python
347
from flask import Flask
348
from jsonrpc.backend.flask import JSONRPCAPI
349
350
app = Flask(__name__)
351
352
# Strict content-type checking (default)
353
strict_api = JSONRPCAPI(check_content_type=True)
354
355
# Flexible content-type handling
356
flexible_api = JSONRPCAPI(check_content_type=False)
357
358
@strict_api.dispatcher.add_method
359
@flexible_api.dispatcher.add_method
360
def echo(message):
361
return message
362
363
app.register_blueprint(strict_api.as_blueprint('strict'), url_prefix='/strict')
364
app.register_blueprint(flexible_api.as_blueprint('flexible'), url_prefix='/flexible')
365
366
# Strict API requires Content-Type: application/json
367
# Flexible API accepts form data and other content types
368
```
369
370
### Method Mapping Views
371
372
```python
373
# Both Django and Flask provide method mapping views
374
375
# Django: Visit /api/map to see available methods
376
# Returns HTML page with method names and docstrings
377
378
# Flask: Visit /api/map to see available methods
379
# Returns HTML page with method names and docstrings
380
381
from jsonrpc import dispatcher
382
383
@dispatcher.add_method
384
def calculate(operation, a, b):
385
"""
386
Perform mathematical calculation.
387
388
Args:
389
operation: Type of operation ('add', 'subtract', 'multiply', 'divide')
390
a: First number
391
b: Second number
392
393
Returns:
394
Result of the calculation
395
"""
396
if operation == 'add':
397
return a + b
398
elif operation == 'subtract':
399
return a - b
400
elif operation == 'multiply':
401
return a * b
402
elif operation == 'divide':
403
return a / b if b != 0 else None
404
405
# Method map will display:
406
# calculate: Perform mathematical calculation. Args: operation: Type of operation...
407
```
408
409
### Production Configuration
410
411
```python
412
# Django settings.py
413
JSONRPC_MAP_VIEW_ENABLED = False # Disable in production
414
415
# Flask production setup
416
from flask import Flask
417
from jsonrpc.backend.flask import JSONRPCAPI
418
import os
419
420
app = Flask(__name__)
421
422
# Disable debug features in production
423
api = JSONRPCAPI()
424
425
if not os.environ.get('DEBUG'):
426
# Remove map endpoint in production
427
@app.route('/api', methods=['POST'])
428
def jsonrpc_endpoint():
429
return api.jsonrpc()
430
else:
431
# Full API with map in development
432
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
433
434
# Add production logging, security headers, etc.
435
```