quickrpc.codecs and .terse_codec modules¶
quickrpc.codecs module¶
Codecs convert message structures into bytes and vice versa.
- Classes defined here:
- Codec: base class
- Message, DecodeError
-
class
quickrpc.codecs.
Codec
[source]¶ Bases:
object
Responsible for serializing and deserializing method calls.
Subclass and override
encode
,decode
, optionallyencode_reply
,encode_error
.Protocol overview
Byte-data payload is generated from python data by using:
encode
for “regular” messages / requestsencode_reply
for return dataencode_error
for error return data.
Python data is retrieved from bytes by
decode
. This returns a list of objects, which can be instances ofMessage
,Reply
andErrorReply
.Security
Let payload denote the “inner” message data and frame the message going on the wire, both being byte sequences.
encode*()
can be given a sec_out() callback, taking the payload data and returning(secinfo, new_payload)
.secinfo is a dict containing e.g. user info, signature, etc. (specific of Security provider).
new_payload is an optional transformed payload (bytes), e.g. encrypted data. If omitted, use original payload.
encode*()
then builds a frame using new payload and secinfo data, e.g. add crypt headers.Depending on protocol, encode could be downwards-compatible if “guest” security applies i.e. secinfo is empty and payload stays untransformed.
Decoding:
decode
again takes a sec_in() callback, accepting security info and payload data, returning the “unpacked” payload. E.g. secinfo could check the signature and raise an error if the message was forged. The secinfo dictionary is returned within theMessage
,Reply
orErrorReply
object.-
decode
(data, sec_in=None)[source]¶ decode data to method call with kwargs.
Return: [messages], remainder where [messages] is the list of decoded messages and remainder is leftover data (which may contain the beginning of another message).
If a message cannot be decoded properly, an exception is added in the message list. Decode should never raise an error, because in this case the remaining data cannot be retrieved.
- messages can be instances of:
- Message
- Reply (to the previous message with the same id)
- ErrorReply (to the previous message with the same id)
- Message attributes
- .method attribute (string), .kwargs attribute (dict), .id, .secinfo (dict)
- Reply attributes
- .result, .id, .secinfo (dict)
- ErrorReply attributes
- .exception, .id, .errorcode, .secinfo (dict)
-
encode
(method, kwargs=None, id=0, sec_out=None)[source]¶ encode a method call with given kwargs.
sec_out callback parameters:
- payload (bytes): Payload data for the frame.
sec_out returns
(secinfo, new_payload)
:sec_info
(dict): security information, dictionary str->str, keys defined by Security provider.new_payload
(bytes): transformed payload;None
indicates that original payload can be used.
Returns: frame data (bytes)
-
encode_error
(in_reply_to, exception, errorcode=0, sec_out=None)[source]¶ encode error caused by the given Message.
-
classmethod
fromstring
(expression)[source]¶ Creates a codec from a given string expression.
The expression must be “<shorthand>:<specific parameters>”, with shorthand being the wanted Codec’s .shorthand property. For the specific parameters, see the respective Codec’s .fromstring method.
-
shorthand
= ''¶
-
exception
quickrpc.codecs.
DecodeError
[source]¶ Bases:
Exception
exception ‘quickrpc.codecs.DecodeError’ undocumented
-
exception
quickrpc.codecs.
EncodeError
[source]¶ Bases:
Exception
exception ‘quickrpc.codecs.EncodeError’ undocumented
-
class
quickrpc.codecs.
Message
(method, kwargs, id=0, secinfo=None)[source]¶ Bases:
object
class ‘quickrpc.codecs.Message’ undocumented
-
class
quickrpc.codecs.
Reply
(result, id, secinfo=None)[source]¶ Bases:
object
class ‘quickrpc.codecs.Reply’ undocumented
-
class
quickrpc.codecs.
ErrorReply
(exception, id, errorcode=0, secinfo=None)[source]¶ Bases:
object
class ‘quickrpc.codecs.ErrorReply’ undocumented
-
exception
quickrpc.codecs.
RemoteError
(message, details)[source]¶ Bases:
Exception
exception ‘quickrpc.codecs.RemoteError’ undocumented
-
class
quickrpc.codecs.
JsonRpcCodec
(delimiter=b'x00')[source]¶ Bases:
quickrpc.codecs.Codec
Json codec: convert to json
bytes values are converted into a an object containing the single key
__bytes
with value being base64-encoded data.If security is used, the following “Authenticated-JSON-RPC” protocol applies:
Encoding
Prepend a special, valid json-rpc message before the payload:
{"jsonrpc": "2.0", "method": "rpc.secinfo", "params": <secinfo>}<DELIM><payload><DELIM>
If secinfo is empty, NOTHING is prepended (i.e. behaves like unextended JSON-RPC)
Note
Payload must not contain the delimiter even if it is encrypted. Raw data could be b64-encoded. If payload is encrypted, basic-JSON-RPC compatibility is of course lost.
Decoding with security
Decode delimited messages one-by-one as usual (“one” being the bytes between delimiters).
If a
rpc.secinfo
call is detected, take the unaltered payload from the next message, giving secinfo and payload. If next message is incomplete (no trailing delim), throw therpc.secinfo
message back into the remainder.For regular call (method !=
rpc.secinfo
), return the message itself as payload wtih empty secinfo.Discussion:
- allows framing without touching payload :-)
- allows decoding the header without decoding payload :-)
- allows using byte-payload as is, particularly allows encrypted+literal payload to coexist (however encrypted payload breaks JSON-RPC compat!) :-)
- Msg to “unaware” peer: will throw the rpc.secinfo calls away silently or loudly, but is able to operate. Missing ID indicates a notification, i.e. peer will not send response back per JSON-RPC spec. :-)
- Msg from “unaware” peer: will implicitly be treated as no-security message.
-
decode
(data, sec_in=None)[source]¶ decode data to method call with kwargs.
Return: [messages], remainder where [messages] is the list of decoded messages and remainder is leftover data (which may contain the beginning of another message).
If a message cannot be decoded properly, an exception is added in the message list. Decode should never raise an error, because in this case the remaining data cannot be retrieved.
- messages can be instances of:
- Message
- Reply (to the previous message with the same id)
- ErrorReply (to the previous message with the same id)
- Message attributes
- .method attribute (string), .kwargs attribute (dict), .id, .secinfo (dict)
- Reply attributes
- .result, .id, .secinfo (dict)
- ErrorReply attributes
- .exception, .id, .errorcode, .secinfo (dict)
-
encode
(method, kwargs, id=0, sec_out=None)[source]¶ encode a method call with given kwargs.
sec_out callback parameters:
- payload (bytes): Payload data for the frame.
sec_out returns
(secinfo, new_payload)
:sec_info
(dict): security information, dictionary str->str, keys defined by Security provider.new_payload
(bytes): transformed payload;None
indicates that original payload can be used.
Returns: frame data (bytes)
-
encode_error
(in_reply_to, exception, errorcode=0, sec_out=None)[source]¶ encode error caused by the given Message.
-
classmethod
fromstring
(expression)[source]¶ jrpc:delimiter
delimiter is the character splitting the telegrams and must not occur within any telegram. Default = <null>.
-
shorthand
= 'jrpc'¶
quickrpc.terse_codec module¶
module ‘quickrpc.terse_codec’ undocumented
-
quickrpc.terse_codec.
L
()¶ function ‘quickrpc.terse_codec.L’ undocumented
-
class
quickrpc.terse_codec.
TerseCodec
[source]¶ Bases:
quickrpc.codecs.Codec
Terse codec: encodes with minimum puncutation.
encodes to: method[id] param1:1, param2:”foo”<NL> values:
- int/float: 1.0
- bytes: ‘(base64-string’
- str: “python-escaped str”
- list: [val1 val2 val3 …]
- dict: {key1:val1 key2:val2 …}
Reply is encoded to: [id]:value Error is encoded to: [id]! message:”string” details:”string”
- Commands must be terminated by newline.
- Newlines, double quote and backslash in strings are escaped as usual
- Allowed dtypes: int, float, str, bytes (content base64-encoded), list, dict
-
decode
(data, sec_in=None)[source]¶ decode data to method call with kwargs.
Return: [messages], remainder where [messages] is the list of decoded messages and remainder is leftover data (which may contain the beginning of another message).
If a message cannot be decoded properly, an exception is added in the message list. Decode should never raise an error, because in this case the remaining data cannot be retrieved.
- messages can be instances of:
- Message
- Reply (to the previous message with the same id)
- ErrorReply (to the previous message with the same id)
- Message attributes
- .method attribute (string), .kwargs attribute (dict), .id, .secinfo (dict)
- Reply attributes
- .result, .id, .secinfo (dict)
- ErrorReply attributes
- .exception, .id, .errorcode, .secinfo (dict)
-
encode_error
(in_reply_to, exception, errorcode=0, sec_out=None)[source]¶ encode error caused by the given Message.
-
shorthand
= 'terse'¶