JSON-RPC transport implementation for Python supporting both 1.0 and 2.0 protocols with Django and Flask backends
—
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.
Complete Django integration with URL patterns, views, and optional method mapping interface.
from jsonrpc.backend.django import JSONRPCAPI
class JSONRPCAPI:
def __init__(self, dispatcher = None):
"""
Initialize Django JSON-RPC API.
Parameters:
- dispatcher: Optional Dispatcher instance (creates new if None)
"""
@property
def urls(self):
"""
Get URL patterns for Django.
Returns:
List of URL patterns for Django routing
"""
def jsonrpc(self, request):
"""
Django view for JSON-RPC endpoint.
Parameters:
- request: Django HttpRequest object
Returns:
HttpResponse with JSON-RPC response
"""
def jsonrpc_map(self, request):
"""
Django view for method mapping display.
Parameters:
- request: Django HttpRequest object
Returns:
HttpResponse with HTML method list
"""
# Pre-created API instance
api: JSONRPCAPI
# Response serialization function
def response_serialize(obj) -> str:
"""Serialize response data with datetime/decimal support."""Complete Flask integration with Blueprint support, views, and flexible configuration.
from jsonrpc.backend.flask import JSONRPCAPI
class JSONRPCAPI:
def __init__(self, dispatcher = None, check_content_type: bool = True):
"""
Initialize Flask JSON-RPC API.
Parameters:
- dispatcher: Optional Dispatcher instance (creates new if None)
- check_content_type: Whether to require "application/json" content-type
"""
def as_blueprint(self, name: str = None):
"""
Create Flask Blueprint with JSON-RPC routes.
Parameters:
- name: Blueprint name (generates UUID if None)
Returns:
Flask Blueprint with routes configured
"""
def as_view(self):
"""
Get view function for manual route registration.
Returns:
View function for Flask route
"""
def jsonrpc(self):
"""
Flask view for JSON-RPC endpoint.
Returns:
Flask Response with JSON-RPC response
"""
def jsonrpc_map(self):
"""
Flask view for method mapping display.
Returns:
Flask Response with HTML method list
"""
# Pre-created API instance
api: JSONRPCAPI# django_project/views.py
from jsonrpc.backend.django import api
# Add methods to the API
@api.dispatcher.add_method
def hello(name):
return f"Hello, {name}!"
@api.dispatcher.add_method
def add(a, b):
return a + b
# django_project/urls.py
from django.urls import path, include
from jsonrpc.backend.django import api
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(api.urls)), # Includes both endpoint and map
]
# Alternative: Manual URL configuration
from django.urls import path
from jsonrpc.backend.django import api
urlpatterns = [
path('jsonrpc/', api.jsonrpc, name='jsonrpc_endpoint'),
path('jsonrpc/map/', api.jsonrpc_map, name='jsonrpc_map'),
]from jsonrpc.backend.django import JSONRPCAPI
from jsonrpc import Dispatcher
# Create custom dispatcher with methods
class MathService:
def add(self, a, b):
return a + b
def multiply(self, a, b):
return a * b
math_dispatcher = Dispatcher()
math_dispatcher.add_object(MathService())
# Create custom API instance
math_api = JSONRPCAPI(dispatcher=math_dispatcher)
# In urls.py
from django.urls import path, include
urlpatterns = [
path('math/', include(math_api.urls)),
]
# Usage: POST to /math/ with JSON-RPC request
# {"jsonrpc": "2.0", "method": "add", "params": [5, 3], "id": 1}from jsonrpc.backend.django import api
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
# Method that uses Django request context
@api.dispatcher.add_method
def get_user_info(request):
"""This method automatically receives the Django request object."""
return {
"user": request.user.username if request.user.is_authenticated else "anonymous",
"method": request.method,
"path": request.path,
"is_ajax": request.headers.get('X-Requested-With') == 'XMLHttpRequest'
}
@api.dispatcher.add_method
def protected_method(secret_data, request):
"""Method that checks authentication via Django request."""
if not request.user.is_authenticated:
from jsonrpc.exceptions import JSONRPCDispatchException
raise JSONRPCDispatchException(
code=-32001,
message="Authentication required"
)
return {"data": secret_data, "user": request.user.username}
# Custom view with authentication
@csrf_exempt
@login_required
def authenticated_jsonrpc(request):
return api.jsonrpc(request)
# In urls.py
urlpatterns = [
path('api/', include(api.urls)), # Public API
path('secure-api/', authenticated_jsonrpc), # Authenticated API
]# app.py
from flask import Flask
from jsonrpc.backend.flask import api
app = Flask(__name__)
# Add methods to the API
@api.dispatcher.add_method
def hello(name):
return f"Hello, {name}!"
@api.dispatcher.add_method
def add(a, b):
return a + b
# Method 1: Using Blueprint
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
# Method 2: Manual route registration
# app.add_url_rule('/api', view_func=api.as_view(), methods=['POST'])
if __name__ == '__main__':
app.run(debug=True)
# Usage:
# POST to /api/ with JSON-RPC request
# GET /api/map to see available methodsfrom flask import Flask
from jsonrpc.backend.flask import JSONRPCAPI
from jsonrpc import Dispatcher
app = Flask(__name__)
# Create custom dispatcher
user_dispatcher = Dispatcher()
@user_dispatcher.add_method
def get_user(user_id):
return {"id": user_id, "name": f"User {user_id}"}
@user_dispatcher.add_method
def create_user(name, email):
return {"id": 123, "name": name, "email": email, "created": True}
# Create custom API
user_api = JSONRPCAPI(dispatcher=user_dispatcher, check_content_type=False)
# Register with different prefixes
app.register_blueprint(user_api.as_blueprint('user_api'), url_prefix='/users')
# Multiple APIs
admin_dispatcher = Dispatcher()
admin_dispatcher["admin.status"] = lambda: {"status": "running", "version": "1.0"}
admin_api = JSONRPCAPI(dispatcher=admin_dispatcher)
app.register_blueprint(admin_api.as_blueprint('admin_api'), url_prefix='/admin')
if __name__ == '__main__':
app.run()from flask import Flask, request
from jsonrpc.backend.flask import JSONRPCAPI
from jsonrpc.exceptions import JSONRPCDispatchException
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
# Custom API with error handling
api = JSONRPCAPI()
@api.dispatcher.add_method
def divide(a, b):
if b == 0:
raise JSONRPCDispatchException(
code=-32602,
message="Division by zero",
data={"dividend": a, "divisor": b}
)
return a / b
@api.dispatcher.add_method
def get_client_info():
"""Return information about the client making the request."""
return {
"remote_addr": request.remote_addr,
"user_agent": request.headers.get('User-Agent'),
"content_type": request.content_type,
"content_length": request.content_length
}
# Custom error handler
@app.errorhandler(500)
def handle_server_error(error):
app.logger.error(f"Server error: {error}")
return {"error": "Internal server error"}, 500
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
if __name__ == '__main__':
app.run(debug=True)from flask import Flask
from jsonrpc.backend.flask import JSONRPCAPI
app = Flask(__name__)
# Strict content-type checking (default)
strict_api = JSONRPCAPI(check_content_type=True)
# Flexible content-type handling
flexible_api = JSONRPCAPI(check_content_type=False)
@strict_api.dispatcher.add_method
@flexible_api.dispatcher.add_method
def echo(message):
return message
app.register_blueprint(strict_api.as_blueprint('strict'), url_prefix='/strict')
app.register_blueprint(flexible_api.as_blueprint('flexible'), url_prefix='/flexible')
# Strict API requires Content-Type: application/json
# Flexible API accepts form data and other content types# Both Django and Flask provide method mapping views
# Django: Visit /api/map to see available methods
# Returns HTML page with method names and docstrings
# Flask: Visit /api/map to see available methods
# Returns HTML page with method names and docstrings
from jsonrpc import dispatcher
@dispatcher.add_method
def calculate(operation, a, b):
"""
Perform mathematical calculation.
Args:
operation: Type of operation ('add', 'subtract', 'multiply', 'divide')
a: First number
b: Second number
Returns:
Result of the calculation
"""
if operation == 'add':
return a + b
elif operation == 'subtract':
return a - b
elif operation == 'multiply':
return a * b
elif operation == 'divide':
return a / b if b != 0 else None
# Method map will display:
# calculate: Perform mathematical calculation. Args: operation: Type of operation...# Django settings.py
JSONRPC_MAP_VIEW_ENABLED = False # Disable in production
# Flask production setup
from flask import Flask
from jsonrpc.backend.flask import JSONRPCAPI
import os
app = Flask(__name__)
# Disable debug features in production
api = JSONRPCAPI()
if not os.environ.get('DEBUG'):
# Remove map endpoint in production
@app.route('/api', methods=['POST'])
def jsonrpc_endpoint():
return api.jsonrpc()
else:
# Full API with map in development
app.register_blueprint(api.as_blueprint(), url_prefix='/api')
# Add production logging, security headers, etc.Install with Tessl CLI
npx tessl i tessl/pypi-json-rpc