# -*- coding: utf-8 -*- # # Copyright (C) 2013 GNS3 Technologies Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ JSON-RPC protocol implementation. http://www.jsonrpc.org/specification """ import json import uuid class JSONRPCObject(object): """ Base object for JSON-RPC requests, responses, notifications and errors. """ def __init__(self): return JSONRPCEncoder().default(self) def __str__(self, *args, **kwargs): return json.dumps(self, cls=JSONRPCEncoder) def __call__(self): return JSONRPCEncoder().default(self) class JSONRPCEncoder(json.JSONEncoder): """ Creates the JSON-RPC message. """ def default(self, obj): """ Returns a Python dictionary corresponding to a JSON-RPC message. """ if isinstance(obj, JSONRPCObject): message = {"jsonrpc": 2.0} for field in dir(obj): if not field.startswith('_'): value = getattr(obj, field) message[field] = value return message return json.JSONEncoder.default(self, obj) class JSONRPCInvalidRequest(JSONRPCObject): """ Error response for an invalid request. """ def __init__(self): JSONRPCObject.__init__(self) self.id = None self.error = {"code": -32600, "message": "Invalid Request"} class JSONRPCMethodNotFound(JSONRPCObject): """ Error response for an method not found. :param request_id: JSON-RPC identifier """ def __init__(self, request_id): JSONRPCObject.__init__(self) self.id = request_id self.error = {"code": -32601, "message": "Method not found"} class JSONRPCInvalidParams(JSONRPCObject): """ Error response for invalid parameters. :param request_id: JSON-RPC identifier """ def __init__(self, request_id): JSONRPCObject.__init__(self) self.id = request_id self.error = {"code": -32602, "message": "Invalid params"} class JSONRPCInternalError(JSONRPCObject): """ Error response for an internal error. :param request_id: JSON-RPC identifier (optional) """ def __init__(self, request_id=None): JSONRPCObject.__init__(self) self.id = request_id self.error = {"code": -32603, "message": "Internal error"} class JSONRPCParseError(JSONRPCObject): """ Error response for parsing error. """ def __init__(self): JSONRPCObject.__init__(self) self.id = None self.error = {"code": -32700, "message": "Parse error"} class JSONRPCCustomError(JSONRPCObject): """ Error response for an custom error. :param code: JSON-RPC error code :param message: JSON-RPC error message :param request_id: JSON-RPC identifier (optional) """ def __init__(self, code, message, request_id=None): JSONRPCObject.__init__(self) self.id = request_id self.error = {"code": code, "message": message} class JSONRPCResponse(JSONRPCObject): """ JSON-RPC successful response. :param result: JSON-RPC result :param request_id: JSON-RPC identifier """ def __init__(self, result, request_id): JSONRPCObject.__init__(self) self.id = request_id self.result = result class JSONRPCRequest(JSONRPCObject): """ JSON-RPC request. :param method: JSON-RPC destination method :param params: JSON-RPC params for the corresponding method (optional) :param request_id: JSON-RPC identifier (generated by default) """ def __init__(self, method, params=None, request_id=None): JSONRPCObject.__init__(self) if request_id == None: request_id = str(uuid.uuid4()) self.id = request_id self.method = method if params: self.params = params class JSONRPCNotification(JSONRPCObject): """ JSON-RPC notification. :param method: JSON-RPC destination method :param params: JSON-RPC params for the corresponding method (optional) """ def __init__(self, method, params=None): JSONRPCObject.__init__(self) self.method = method if params: self.params = params