CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-json-rpc

JSON-RPC transport implementation for Python supporting both 1.0 and 2.0 protocols with Django and Flask backends

Pending
Overview
Eval results
Files

backends.mddocs/

Backend Integrations

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.

Capabilities

Django Backend

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."""

Flask Backend

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

Usage Examples

Django Integration

# 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'),
]

Custom Django API

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}

Django with Context Injection

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
]

Flask Integration

# 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 methods

Custom Flask API

from 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()

Flask with Error Handling

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)

Content Type Handling

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

Method Mapping Views

# 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...

Production Configuration

# 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

docs

backends.md

core-jsonrpc.md

dispatcher.md

exceptions.md

index.md

requests-responses.md

tile.json