Passed
Push — master ( 1de29a...581576 )
by Michael
03:27
created

JsonRpcRequest.from_dict()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 10
rs 9.95
c 0
b 0
f 0
cc 1
nop 3
1
import typing
2
3
from .. import constants, errors, utils
4
5
6
__all__ = (
7
    'JsonRpcRequest',
8
)
9
10
11
class JsonRpcRequest:
12
    msg_id: typing.Any
13
    method: str
14
    jsonrpc: str
15
    extra_args: dict
16
    context: dict
17
    _params: typing.Any
18
    _args: list
19
    _kwargs: dict
20
21
    def __init__(self, *,
22
                 msg_id: typing.Any = constants.NOTHING,
23
                 method: str,
24
                 jsonrpc: typing.Any = constants.VERSION_2_0,
25
                 params: typing.Any = constants.NOTHING,
26
                 args: typing.Any = None,
27
                 kwargs: typing.Any = None,
28
                 context: typing.Optional[dict] = None) -> None:
29
        utils.validate_jsonrpc(jsonrpc)
30
31
        self.msg_id = msg_id
32
        self.method = method
33
        self.jsonrpc = jsonrpc
34
        self.extra_args = {}
35
        self.context = {} if context is None else context
36
37
        if params is constants.NOTHING:
38
            self.args_and_kwargs = args, kwargs
39
        elif not args and not kwargs:
40
            self.params = params
41
        else:
42
            raise errors.InvalidParams('Need use params or args with kwargs.')
43
44
    @property
45
    def params(self) -> typing.Any:
46
        return self._params
47
48
    @params.setter
49
    def params(self, value: typing.Any) -> None:
50
        self._params = value
51
        self._args, self._kwargs = utils.convert_params_to_args_and_kwargs(value)
52
53
    @property
54
    def args(self) -> list:
55
        return self._args
56
57
    @property
58
    def kwargs(self) -> dict:
59
        return self._kwargs
60
61
    @property
62
    def args_and_kwargs(self) -> typing.Tuple[list, dict]:
63
        return self._args, self._kwargs
64
65
    @args_and_kwargs.setter
66
    def args_and_kwargs(self, value: typing.Tuple[typing.Optional[list], typing.Optional[dict]]) -> None:
67
        self._params, self._args, self._kwargs = utils.parse_args_and_kwargs(*value)
68
69
    @property
70
    def is_notification(self) -> bool:
71
        return self.msg_id is constants.NOTHING
72
73
    @classmethod
74
    def from_dict(cls, data: typing.Dict[str, typing.Any], **kwargs) -> 'JsonRpcRequest':
75
        cls._validate_json_request(data)
76
77
        return cls(
78
            msg_id=data.get('id', constants.NOTHING),
79
            method=data['method'],
80
            params=data.get('params', constants.NOTHING),
81
            jsonrpc=data['jsonrpc'],
82
            **kwargs,
83
        )
84
85
    def to_dict(self) -> dict:
86
        data = {
87
            'method': self.method,
88
            'jsonrpc': self.jsonrpc,
89
        }
90
91
        if not self.is_notification:
92
            data['id'] = self.msg_id
93
94
        if self.params is not constants.NOTHING:
95
            data['params'] = self.params
96
97
        return data
98
99
    @staticmethod
100
    def _validate_json_request(data: typing.Any) -> None:
101
        if not isinstance(data, dict):
102
            raise errors.InvalidRequest('A request must be of the dict type.')
103
104
        if not ({'method', 'jsonrpc'}) <= data.keys():
105
            raise errors.InvalidRequest('A request must contain "method" and "jsonrpc".')
106
107
        utils.validate_jsonrpc(data['jsonrpc'])
108